Добрый день! Как известно, протокол tcp обеспечивает гарантированную доставку пакетов благодаря посылке ответных пакетов с флагом ACK. Однако, в indy возникает следующая ситуация:
Код:
TCPClient.Connect;
TCPClient.Socket.SendBufferSize:=1000;
TCPClient.Socket.RecvBufferSize:=1000;
for i := 0 to 100 do
begin
strm.SetSize(1000+i);
strm.Position:=0;
TCPClient.Socket.BeginWork(wmWrite, strm.Size);
TCPClient.Socket.Write(strm,strm.Size,true);
memo1.lines.add('send '+IntToStr(strm.Size));
Application.ProcessMessages;
TCPClient.Socket.EndWork(wmWrite);
end;
TCPClient.DisConnect;
такой клиент, например, посылает 20 пакетов в секунду. А такой сервер:
Код:
procedure TForm2.TCPServerExecute(AContext: TIdContext);
begin
strm:= tmemorystream.Create;
AContext.Connection.Socket.RecvBufferSize:=1000;
AContext.Connection.Socket.SendBufferSize:=1000;
for i := 0 to 100 do
begin
strm.SetSize(0);
AContext.Connection.Socket.BeginWork(wmRead,0);
sleep(100);
AContext.Connection.Socket.ReadStream(strm, -1, false);
memo1.lines.add('receive '+IntToStr(strm.Size));
Application.ProcessMessages;
AContext.Connection.Socket.EndWork(wmRead);
end;
strm.Free;
end;
принимает всего 10 пакетов в секунду. Остальные, вероятнее всего буфферизуются где-то, несмотря на четко указаный буфер размером в 1 пакет.
Отсюда вопрос: как сделать так, чтобы следующий пакет не отсылался до тех пор, пока не будет хотя бы обработан функцией ReadStream (про дальнейшую обработку я уже молчу)???
На данный момент я реализую это обратным пакетом - но это черезчур нагружает сеть. Да и получается эмуляцией ACK на прикладном уровне...
PS: я пробовал работать с транзакциями, пытался сделать Socket.WriteBufferOpen и Socket.WriteBufferClose до и после записи в сокет, но все впустую. Видно, что пакет уходит в сеть сразу в момент Write. Но и сразу же приходит ACK-пакет, а обрабатывается этот пакет много позднее.