Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2002.08.08;
Скачать: [xml.tar.bz2];

Вниз

socket   Найти похожие ветки 

 
CrazyTemo   (2002-05-22 17:53) [0]

как синхронизавать socket? то есть как контролиравать передачу дааных? например когда я посилаю текст, сервер получает все в месте, а я хочу получать каждую строку отделно


 
KPOT   (2002-05-22 18:46) [1]

Читай по одному символу до контрольного знака


 
cyborg   (2002-05-23 09:18) [2]

CrazyTemo Ничего не нужно контролировать, сокет сам уже всё контролирует, вот вставь себе в программу такой код:


Const Delitel : String = #13#10;
{Разделитель строк, добавляется в конец отсылаемых данных, можно написать любой, какой нравится}

---------
{Процедура обработки мессаг S-передаваемая строка,
Socket - Передаваемый сокет откуда пришла мессага}
Procedure Process_Message(Var S : AnsiString;Var Socket: TCustomWinSocket);
Begin
{Обрабатываем здесь полученные данные}
End;


procedure TMyForm.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
Var S,_S : AnsiString;
I : Integer;
begin
S:=Socket.ReceiveText;
I:=0;
Repeat {Разделяем строку, если одновременно пришло несколько}
I:=Pos(Delitel,S); {Ищем радлелитель Delitel}
if I<>0 then {Если найден делитель, тогда ... Если не найден, то ты не добавил в конце отсылаемой строки Delitel !}
Begin
_S:=Copy(S,1,I-1);{Копируем одну мессагу}
Delete(S,1,I+Length(Delitel)-1);
{Удаляем уже скопированную мессагу}
Process_Message(_S,Socket);
{Процедура обработки мессаг где _S наша выделенная мессага}
End;
Until I=0;
end;

{Пример отправки мессаг}
Socket.SendText("Ку ку!"+Delitel); {Важно добавлять в конце каждой отправляемой строки разделитель строк Delitel}

-----------------
Всё должно работать :-) ...


 
Digitman   (2002-05-23 11:01) [3]

>cyborg
Это не будет работать ожидаемым образом. Неверно представляешь себе логику метода ReceiveText().


 
Fredericco   (2002-05-23 16:51) [4]

cyborg © >> Если на том конце всегда добавлять #13#10 если нет физических сбоев или резкого зависания системы, то на другом конце ты всегда увидишь #13#10.


 
cyborg   (2002-05-23 20:02) [5]

Digitman ©
А что за работа неожиданным образом?
Однако работает :-). У меня всё прекрасно делит. Хотя всё может быть. Расскажите поподробнее.

Fredericco ©
:-) На том и состоит код, что разделитель видно и по нему разбивается, т.е. не понял смысл ваших слов.

А вот сбои :-), это просто беда ...


 
Malder   (2002-05-23 21:28) [6]

Я тоже не понял претензии Digitman"а


 
Donal_Graeme   (2002-05-24 09:18) [7]

2 cyborg: у тебя не предусмотрено, что сообщения могут быть разбиты. т.е. ты отправляешь "абвгд#13#10" а получатель сперва получает "аб" а потом "вгд#13#10".


 
Digitman   (2002-05-24 09:43) [8]

Пусть передающая сторона выполнила следующее :


1. Socket.SendText("Ку ку!"+Delitel);
2. Socket.SendText("Ку ку!"+Delitel);
3. Socket.SendText("Ку ку!"+Delitel);


где

Delitel = #13#10


Тогда не исключена ситуация, что в момент возникновения на принимающей стороне самого первого (с момента старта приема) события TCustomWinSocket.OnRead() в буфере приема гнезда будет доступен след.поток данных :


Ку ку!#13#10 #0Ку ку!#13#10 #0Ку ку!#13#10 #0


всего - 27 символов; в реальности может быть и меньше из за особенности TCP-транспорта

Согласно приведенному коду от <cyborg © (23.05.02 09:18)> первая же инструкция, выполняемая в теле OnRead(), это


S:=Socket.ReceiveText;


Теперь посмотрим, что "творится" в теле метода ReceiveText() :


function TCustomWinSocket.ReceiveText: string;
begin
//получить ожидаемый приемником размер данных
//ReceiveBuf(Pointer(nil)^, -1) <= 27
//и установить для результирующей Ansi-строки длину,
//равную этому (максимально возможному в дан.момент) значению

SetLength(Result, ReceiveBuf(Pointer(nil)^, -1));

//прочитать из буфера приема и скопировать в буфер результ.строки
// действительно доступные данные размером, возвращенным
//при вызове ReceiveBuf(Pointer(Result)^, Length(Result));

//скорректировать длину результ.строки так, чтобы ее буфер занимал в памяти ровно столько, сколько в действительности удалось принять

SetLength(Result, ReceiveBuf(Pointer(Result)^, Length(Result)));
end;



Не исключено, что по завершению метода TCustomWinSocket.ReceiveText() результ.строка будет содержать следующее :


Ку ку!#13#10 #0Ку ку!#13#10 #0Ку ку!#13#10 #0 #0


Обратим внимание, что в конце стоят 2 символа-терминатора, последний из которых добавлен автоматически при вызове SetLength()

Теперь смотрим, что происходит при выполнении собственно присваивания в строчке

S:=Socket.ReceiveText;


Первым же делом выполняется определение актуального (!) размера строки, возвращенной методом ReceiveText() для выделения необходимого размера памяти под буфер строки S; актуальный размер Ansi-строки будет равен числу байт от начала строкового буфера до первого встреченного символа-терминатора #0
В принятой строке позиция первого терминатора равна 9, поэтому размер строки S будет установлен равным 8, а ее содержимое равным "Ку ку!"#13#10.
Остальные (следующие за первыми девятью) 18 символов копируемого при присвоении буфера исходной строки будут проигнорированы и безвозвратно утеряны !! И никакие "специальные" терминаторы Delitel не могут изменить эту ситуацию.

Резюме : надежный (без потерь) прием данных, имеющих текстовый формат, при непрерывном сеансе работы гнездового соединения в поточном режиме на принимающей стороне не может быть осуществлен с помощью метода ReceiveText(). Для реализации поточного приема текстовых строк в рамках одного и того же соединения следует применять иные способы работы с буфером приема, не задействующие стандартные строковые ф-ции Object Pascal"я.

С учетом всех этих замечаний поточные прием/передача текста должны быть организованы в самом простом случае, например, след.образом :

1. Передача

var
S: String;
len: Integer;
...
S := "Ку ку!";
len := Length(S);
...
//передача размера передаваемых следом стр.данных
Socket.SendBuf(len, SizeOf(len));
//передача собственно стр.данных
Socket.SendBuf(@S[1], len);

//снова - передача размера передаваемых следом стр.данных
Socket.SendBuf(len, SizeOf(len));
//снова - передача собственно стр.данных
Socket.SendBuf(@S[1], len);

//снова - передача размера передаваемых следом стр.данных
Socket.SendBuf(len, SizeOf(len));
//снова - передача собственно стр.данных
Socket.SendBuf(@S[1], len);

... и т.д. ....


2. Прием


procedure TMyForm.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
Var
cnt
len: Integer;
buf: PChar;
S: String;
begin
cnt := Socket.ReceiveBuf(len, SizeOf(Len));
if cnt < SizeOf(Len) then begin
Socket.Close;
... генерация исключения рассинхронизации приема ...
end;
SetLength(S, len);
buf := PChar(S);
while len > 0 do begin
cnt:= Socket.ReceiveBuf(buf^, Len);
if cnt = 0 then begin
Socket.Close;
... генерация исключения рассинхронизации приема ...
end;
Dec(len, cnt);
Inc(buf, cnt);
end;
Process_Message(S,Socket); //передача принятой строки на обработку
end;


 
cyborg   (2002-05-24 10:49) [9]

Digitman © Я думаю вы ошибаетесь.
Тот способ, который я привёл, я использую не для простоой передачи строки, а строки с коммандами. Команды это байты, которые могут иметь и значение 0 и этим способом всё прекрасно передаётся и получается. Я думаю (может ошибаюсь) AnsiString имеет такой же формат как и обычная Паскалевская строка, только размером до 2-х гигабайт и она не заканчивается символом #0.

В моём чате передаётся такая строка:
1-й байт - команда
2-й байт - дополнительная команда
3-й байт - Номер картинки
4-7 байты - Integer - Цвет.
С 8-ого идёт строка сообщения

И все эти байты могут содержать нулевые значения. Особенно цвет, он как известно хранится в Integer который занимает 4 байта, а сам цвет состоит из 3-х байт, и первый в этом значении всегда #0 (нулевой). И этим способом всё работает прекрасно! И при передаче никаких лишних #0 не прибавляется. Возможно вы говорите о ранних версиях Delphi, может там и работает так как вы сказали, но по крайней мере в Delphi6 всё прекрасно работает. Можете сами проверить.


 
Crazytemo   (2002-05-24 11:28) [10]

izvinite ia po ruski ploxo pechataiu. ia nashol takoe reshenie, kogda otsilay odny stroky , jdu poka ne poluchu podtverjdenie i tolko potom posilau sleduyshuiu stroky. chto dumaeeto po etomy povodu?

vot primer:


Socket.sendtext("1 stroka");
while recevied<>true do
socket.receivetext;

Socket.sendtext("2 storka");


 
Digitman   (2002-05-24 11:40) [11]

>cyborg

1. 6-ки у меня нет под рукой, поэтому сравнить реализации SendText() и ReceiveText() с версиями менее 6-й не могу. Но думаю, что и в 6-ке реализации этих методов содержат ту же логику, что и в предыдущих версиях. Приведи, пожалуйста, текст реализации одноименных методов в 6-ке, я сравню их и прокомментирую различия в функц-ти (если таковые будут).

2. Интересно, как это ты вообще умудряешься транслировать бинарные данные собственного формата методом, предназначенным исключительно для трансляции текстовых данных стандартного формата ?
В твоем примере я не увидел ничего кроме SendText()/ReceiveText(), т.е. только "чистый" текст и ничего более. Для любых же стороковых типов символ-терминатор #0 (байт/слово со значением 0) всегда обозначает логический конец текста, и все, что за терминатором, попросту отбрасывается и не принимается во внимание.

3. Твои абстрактным, не подтвержденным аргументами заявлениям о том, что то, что ты здесь привел (с точностью до назначения каждой строчки приведенного кода), работает так как это и ожидается по логике, я противопоставил достаточно детальный разбор механизма работы упомянутых тобой методов. Укажи мне аргументированно на ошибки или несуразицы в изложенном мной - и я немедленно и публично сниму перед тобой шляпу, а автор получит точное представление того, как это д.б. реализовано и как работает в действительности. И да восторжествует истина !))))


 
cyborg   (2002-05-24 13:02) [12]

Я согласен, что этот способ не идеальный, и подходит только для передачи строк, ведь Delitel может совпасть с данными :-) и получится фигня.
В этом случае нужно использовать SendBuf и ReceiveBuf добавляя в начало размер отсылаемых данных, что бы потом сравнивать пришедшее...
Но идея та же ... Получать данные в SocketRead Смотреть что пришло, если нужно - разделить, если недопришло - дополучить, а потом всё передавать функции Process_Messages ...


 
Digitman   (2002-05-24 13:14) [13]

>cyborg

Да не то что "не идеальный" ! Вообще не подходит. А ты тем не менее совет даешь автору...


 
cyborg   (2002-05-24 13:27) [14]

Const
Delitel : String =#13#10; {Разделитель передаваемых строк с помощью которого узнаётся сколько строк прислали}
{Команды Command:}
CDisconnect = 0; {Клиент сообщает что отсоединяется}
CPassword = 1; {Пароль от клиента}
CName = 2; {Имя клиента}
CMessage = 100; {Пришла обычная мессага для всех}
CPrivate = 101; {Мессага для конкретного IP}
CClientConnect = 200; {Подключился клиент}
CClientDisconnect = 201; {Отключился клиент}
CLive = 255; {Клиент напоминает о себе что в сети, должно приходить каждые N секунд}


Function CodeChatString(Const Command,SecondCommand,Face : Byte;
Const Color : Integer; Const Messaga : AnsiString) : AnsiString; {Все комманды в одну строку}
Var S : AnsiString;
IntS : array[0..3] of char;
Begin
IntS:=#0#0#0#0;
Move(Color,IntS,4);
S:=Chr(Command)+Chr(SecondCommand)+Chr(Face)+IntS[0]+IntS[1]+IntS[2]+IntS[3]+Messaga;
Result:=S;
End;

Procedure DecodeChatString(StringToDecode : AnsiString;
Var Command,SecondCommand,Face : Byte;
Var Color : Integer;Var Messaga : AnsiString); {Расшифровать коммандную строку}
Var
S : AnsiString;
I : Integer;
Begin
S:=StringToDecode;
Command:=Ord(S[1]);
SecondCommand:=Ord(S[2]);
Face:=Ord(S[3]);
Move(S[4],I,4);Color:=I;
Delete(S,1,7);
Messaga:=S;
End;

{Эта та самая Process_Messages}
Procedure _Messages(Var _S : AnsiString;Var Socket: TCustomWinSocket);
{Обработать сообщение}
Var
S : AnsiString;
Command,SecondCommand,Face : Byte;
Color : Integer;
Messaga : String;
ListItem : TListItem;
_Data : PData;
I : Integer;
Begin
S:=_S;
DecodeChatString(S,Command,SecondCommand,Face,Color,Messaga); {Расшифровать коммандную строку}

Case Command of
CDisconnect : Begin
End;
CPassword : Begin
End;
CName : Begin
GetMem(_Data,SizeOf(ZData));
_Data.Name:=Messaga;
_Data.Color:=Color;
_Data.Face:=Face;
_Data.Tag:=SecondCommand;
ListItem:=MyForm.ListBoxChaters.Items.Add;
ListItem.ImageIndex:=Face;
ListItem.Caption:=Messaga;
ListItem.Data:=_Data;
// MyForm.ListBoxChaters.Items.Add(Messaga);
_DelLines;
MyForm.EditChat.SelAttributes.Color:=clFuchsia;
MyForm.EditChat.Lines.Add("-> ("+TimeToStr(Time)+") в чате: "+Messaga);
_ScrollWindow;
End;
CMessage : Begin
_DelLines;
MyForm.EditChat.SelAttributes.Color:=Color;
MyForm.EditChat.SelAttributes.Style:=[fsBold];
MyForm.EditChat.Lines.Add(Messaga);
_ScrollWindow;
End;
CPrivate : Begin
End;
CClientConnect : Begin
End;
CClientDisconnect : Begin
_Data:=Nil;
Repeat
_Data:=MyForm.ListBoxChaters.FindCaption(0,Messaga,True,False,False).Data;
if (_Data.Name=Messaga) and (_Data.Face=Face) and (_Data.Tag=SecondCommand) then
Begin
I:=MyForm.ListBoxChaters.FindData(0,_Data,False,False).Index;
MyForm.ListBoxChaters.Items.Delete(I);
FreeMem(_Data,SizeOf(ZData));
_Data:=Nil;
End;


Until _Data=Nil;
_DelLines;
MyForm.EditChat.SelAttributes.Color:=clFuchsia;
// MyForm.EditChat.SelAttributes.Style:=[fsBold];
MyForm.EditChat.Lines.Add("-> ("+TimeToStr(Time)+") вышел из чата: "+Messaga);
_ScrollWindow;
End;
CLive : Begin
End
else Begin
End;
End; {case}

End;

procedure TMyForm.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
Var S,_S : AnsiString;
I : Integer;
begin
S:=Socket.ReceiveText;
I:=0;
Repeat {Разделяем строку, если одновременно пришло несколько}
I:=Pos(Delitel,S); {Ищем радлелитель Delitel}
if I<>0 then
Begin
_S:=Copy(S,1,I-1);{Копируем одну мессагу}
Delete(S,1,I+Length(Delitel)-1); {Удаляем уже скопированную мессагу}
_Messages(_S,Socket);{Процедура обработки мессаг где _S наша выделенная мессага}
End;
Until I=0;
end;


procedure TMyForm.Edit1KeyPress(Sender: TObject; var Key: Char);
Var S : String;
begin
if ClientSocket1.Active then
if Key=#13 then
if Edit1.Text<>"" then
Begin
Key:=#0;
S:=CodeChatString(CMessage,0,0, ClientColor.Brush.Color,Edit1.Text);
ClientSocket1.Socket.SendText(S+Delitel);
Edit1.Clear;
End;
end;


Вот вырезал из программы, не стал редактировать не нужные в примере функции, думаю и так поймёте.

Так как Delitel может совпасть с данным в дальнейшем всё это переделаю под SendBuf и ReceiveBuf, а так всё работает :-)


В Delphi6 так:

function TCustomWinSocket.SendText(const s: string): Integer;
begin
Result := SendBuf(Pointer(S)^, Length(S));
end;

function TCustomWinSocket.ReceiveText: string;
begin
SetLength(Result, ReceiveBuf(Pointer(nil)^, -1));
SetLength(Result, ReceiveBuf(Pointer(Result)^, Length(Result)));
end;


 
cyborg   (2002-05-24 13:30) [15]

Если вы не верите что работает :-), то зайдите на мою пагу и скачайте рабочий чат http://www.buzuluk.ru/~cyborg


 
cyborg   (2002-05-24 13:40) [16]

function TCustomWinSocket.SendText(const s: string): Integer;
begin
Result := SendBuf(Pointer(S)^, Length(S));
end;

Обратите внимание на Length(S), здесь S - String, а не PChar, так что отправляемое никак не имеет в конце #0.

--------

function TCustomWinSocket.ReceiveText: string;
begin
SetLength(Result, ReceiveBuf(Pointer(nil)^, -1));
SetLength(Result, ReceiveBuf(Pointer(Result)^, Length(Result)));
end;

Здесь ReceiveBuf, все работает с конкретным Pointer, а не ссылается на PChar который имеет в конце #0, так что и здесь никак не прибавляется #0.


 
Digitman   (2002-05-24 14:12) [17]

>cyborg

Молодец !! Браво !! Не поддался на провокацию !)
Снимаю шляпу) .. Все, что я ожидал - приведение и анализ тобой в кач-ве контраргумента тела метода TCustomWinSocket.SendText().

Действительно, нуль-терминаторы не помещаются передатчиком в поток, поэтому принятой в OnRead() с пом.метода ReceiveText() строкой будет считаться все актуально доступные данные в момент выполнения метода. А вот все ли целиком строки, действительно и последовательно отправленные передатчиком, будут составлять целое содержимое полусенной приемником строки - это уже вопрос. В лок.сети еще можно как-то понадеяться на маловероятность ситуации с "разрывом" строк, но в глоб.сети такой фокус заведомо не прокатит - оч.часто приемник будет получать "рваные" на куски строки


 
cyborg   (2002-05-24 14:22) [18]

Ещё прошу заметить что
SendText и ReceiveText этот те же самые SendBuf и ReceiveBuf, только размер не нужно указывать, так как они сами вычисляют размер строки.


А теперь так и хочется сказать :-)
Снимайте шляпы господа!


 
cyborg   (2002-05-24 14:28) [19]

Ой запоздал с мессагой :-), набирал в оффлине, поэтому :-)).
Да, меня убедили, что нужно ещё и проверять на то, что полностью получено или оборванно, займусь как нибудь этим кодом, выложил пока в UBPFD тот, который я привёл. Потом глядишь и универсальный помещу, может кто и лучше сделает, чему я буду рад :-)


 
Digitman   (2002-05-24 15:08) [20]

>cyborg
Рановато ты загордился, однако)
Нет, далеко не те же самые ! И дело даже не в автовычислении размера.

SendBuf/ReceiveBuf предназначены для передачи/приема ЛЮБЫХ бинарных данных, без привязки к конкретному формату.

А касаемо SendText/ReceiveText попробуй-ка в ЛВС и прокомментируй следующее :

var
s: string;
r: string;
..
s:= "Ку ку !";
s[3]:= #0;
ShowMessage(s);
...
Socket.SendText(S);
...
r:= Socket.ReceiveText;
ShowMessage(r);

Вопрос : s = r ? Почему ?




 
Malder   (2002-05-24 18:54) [21]

А почему нет ?


 
cyborg   (2002-05-24 18:56) [22]

Господи, это очередная ваша провокация?
Если да, то я так понимаю, что вы меня проверяете на знания :-).
Ну, а если нет, то я не понимаю зачем вам дали значёк мастера?

Значит вот что я сворганил

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp;

type
TfmHead = class(TForm)
Client: TClientSocket;
Server: TServerSocket;
procedure FormActivate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ServerClientRead(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;

var
fmHead: TfmHead;

implementation

{$R *.dfm}

procedure TfmHead.FormActivate(Sender: TObject);
Var
s: Ansistring;
begin
Server.Open;
Client.Open;
s:= "Ку ку !";
s[3]:= #0;
ShowMessage(s);
Client.Socket.SendText(S);


end;

procedure TfmHead.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Client.Close;
Server.Close;
end;

procedure TfmHead.ServerClientRead(Sender: TObject;
Socket: TCustomWinSocket);
Var
r: Ansistring;
begin
r:= Socket.ReceiveText;
ShowMessage(r);
end;

end.


Так действительно как будто не работает. Почему, скажу позже.

А вот теперь работает:


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp;

type
TfmHead = class(TForm)
Client: TClientSocket;
Server: TServerSocket;
procedure FormActivate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ServerClientRead(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;

var
fmHead: TfmHead;

implementation

{$R *.dfm}

procedure TfmHead.FormActivate(Sender: TObject);
Var
s: Ansistring;
begin
Server.Open;
Client.Open;
s:= "Ку ку !";
s[3]:= #0;
ShowMessage(s);
Client.Socket.SendText(S);


end;

procedure TfmHead.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Client.Close;
Server.Close;
end;

procedure TfmHead.ServerClientRead(Sender: TObject;
Socket: TCustomWinSocket);
Var
r: Ansistring;
I : Integer;
begin
r:= Socket.ReceiveText;
For I:=1 to Length(r) do
if r[I]=#0 then r[I]:="X";
ShowMessage(r);
end;

end.


Так как в ShowMessage использует WinAPI, известно что все строки там передаются PChar-ами. И естественно на экран не выводится то, что после #0. Но стоит заменить в пришедшей строке #0 например на X то мы увидим, чтот вся строка пришла полностью.


Ну что, сделал я мастера :-)? Ну признайтесь ...


 
Crazytemo   (2002-05-25 08:10) [23]

prblema zakluchaetsia isho vodnom, kto nebud iz vas probival posilat bolshoi fail ispolzuia sendtext? ia probival i polucaheetsia takaia vesh, programa zavisaet i potom windows krichit:))) mol ne xvataet operativnoi pamiati. mne ne nujno otsilat bolshie faili, no vsio ravno intersesno pochemu eto proisxodit


 
cyborg   (2002-05-25 09:19) [24]

:-) Как уже сказали, SendText предназначен для посылки строк, а не файлов.
А винды при этом не зависают, а отсылают твой файл, при этом программа не работает, как бы зависла.
Используй для передачи данных SendBuf ReteiveBuf!
Если так уж хочется переслать SendText-ом, то дели файл на части, например по 500 байт, 1 килобайт, короче на твоё усмотрение, и в начале каждой строки вставляй размер отсылаемого блока и номер части файла, что бы потом при получении всё сложить. При полученнии читаешь из полученной строки размер и номер части файла, сравниваешь размер с пришедшими данными, если не совпало, сохраняешь что уже пришло, что бы при повторной загрузке качать не заново, а продолжить. Если всё пришло нормально, складываешь полученные участки в порядке, в котором указано в номере чати файла. Перед передачей, можно посылать название файла, который хочешь передать, если уже такой передавался и оборвался, посылаешь ответ, что такой то файл нужно передавать с такого то размера, та строкона получает эту команду и продолжает кидать тебе файл с места обрыва. А для точности передачи данных, можно придумать контрольную сумму, если не сомпала, то посылаешь что такой то (с номером участок) нужно заново прислать.

Надеюсь понял, что я понаписал :-)


 
Crazytemo   (2002-05-25 09:31) [25]

eto ia ponimaiu vo pervix ia ne xochu ispolzovat senbuf, vo vtorix kogda otsialetsia text file tam tiriatsia simvol konca stroki i prixodetsia dobovliat #13#10 na konce kajdoi stroki , i vtretix problema ni vtom chto eta ne rabotaet , a v tom cto ne rabotaet na bolshix failax na malenkix bez problem. i isho sendtext toje samoe chto sendbuf, tak chtno kakoi smisl ispolzivat sendbuf?. u menia logika takaia otsialau stroky jdu potdtverjdenia i posilau sleduishii. to es problem ne daljno bit. tolko ne gavarite shas chto eto glupo posilat kajduio storky otdelno:))). poprobuite sami sdelat eto i uvidite,


 
cyborg   (2002-05-25 17:46) [26]

Для текстовых файлов можно использовать этот способ пересылки построчно, читать строку, потом посылать, а что если строка в файле длинной ОГОГО?
SendText и SendBuf одно и тоже в смысле используемого метода, но не одно и то же для использования!
Есть ещё SendStream() предназначенный для передачи потока.

Короче итог: SendText для передачи файлов не подходит и использовать его так, просто глупо, когда есть специально предназначенные для этого вещи.


 
Digitman   (2002-05-27 08:54) [27]

>cyborg

Да все нормально, не волнуйся)... Больше "провокаций" не будет)...

Все верно :
strlen(s) <> length(s),
так же как
strlen(r) <> length(r)









Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2002.08.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.71 MB
Время: 0.058 c
4-24271
DeMoN-777
2002-06-02 03:31
2002.08.08
Элементы листбокса чужой программы.


3-23873
Борис
2002-07-17 09:58
2002.08.08
Как оптимизировать вычисление одного столбца от друго(код внутри)


1-23997
iNew
2002-07-26 18:19
2002.08.08
Прочита в хелпе про stdcall и др. дериктивы и ничё не понял,


1-24029
dim-
2002-07-29 09:28
2002.08.08
ListView


1-23983
Mr. JS
2002-07-27 13:19
2002.08.08
Имя узла в TreeView?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский