-
Как реализовать этот аккомулятор и машину состояния?
-
Вы имеете в виду такую конструкцию...
var
ac, readlen : integer;
begin
FillChar( fRequest, REQUESTSIZE, 0 );
ac := 0;
repeat
readlen := fSocketStream.Read( fRequest[ac],1024 );
ac := ac+readlen;
until ( readlen = 0 ) or ( ac = REQUESTSIZE );
end;
-
Даже для трёх байт такое надо делать?
-
> Даже для трёх байт такое надо делать?
Да, даже для двух.
Если тебе пообещали налить бутыль и ты ждешь обещанное, то это вовсе не означает,что ее нальют тебе все разом и сей секунд после обещания - тебе ее когда-нибудь обязательно нальют, но вправе наливать ее через заранее неизвестного/меняющегося диаметра воронку и заранее неизвестными порциями.
Так что готовь тару объемом в бутыль и жди пока она наполнится, коль договорились)
Время наполнения и порции, коими наполнение должно происходить, в общем случае тебе не известно)
-
> FillChar( fRequest, REQUESTSIZE, 0 );
А это вообще нафиг не нужно.
-
А в этой функции лучше ставить минимум или максимум? readlen := fSocketStream.Read( fRequest[ac],1024 ); Тобишь 1 или 17?
-
приведи протокол устройтсва...
-
dozcent © (10.08.08 23:26) [21] Вы имеете в виду такую конструкцию...почти procedure ReadBufferEx(SocketStream:TWinSocketStream;var Buffer; Count: Longint);
var
PBuffer:PByte;
Readed:integer;
begin
PBuffer:=@Buffer;
while Count>0 do
begin
readed:=SocketStream.Read(PBuffer^,Count);
Dec(Count,readed);
Inc(PBuffer,readed);
end;
end;
-
Должно получиться чтото типа этого: procedure TServerClientThreadEx.ClientExecute;
var
SocketStream:TWinSocketStream;
Packet:array[0..16] of byte;
Packet2:array[0..2] of byte;
begin
try
SocketStream:=TWinSocketStream.Create(ClientSocket, 30);
try
while (not Terminated) and (ClientSocket.Connected) do
begin
if not SocketStream.WaitForData(SocketStream.TimeOut) then
raise Exception.Create('Protocol: timeout');
ReadBufferEx(SocketStream,Packet,SizeOf(Packet));
LogServerEvents('Packet Readed');
if ClientSocket.ReceiveLength<>0 then
LogServerEvents('Packet fully Readed, but some socket data still avaliable... Error?');
SetString(IMEI,Packet,SizeOf(Packet));
ConnectToDb;
try
if DeviceInDB then
begin
if UpdateTime then
begin
CreatePackage;
SendingMessage;
if not SocketStream.WaitForData(SocketStream.TimeOut) then
raise Exception.Create('Protocol: timeout');
ReadBufferEx(SocketStream,Packet2,SizeOf(Packet2));
LogServerEvents('Packet2 Readed');
if ClientSocket.ReceiveLength<>0 then
LogServerEvents('Packet2 fully Readed, but some socket data still avaliable... Error?');
if Packet2[2]>=MessCount then
begin
SetUpUpdateTime;
LogConnection(1);
end else
begin
LogConnection(2);
end;
end else
begin
LogConnection(3);
end;
end else
begin
SendingMessageToNewDevice;
LogConnection(4);
end;
finally
DisconnectFromDb;
end;
LogServerEvents('We finish Protocol loop');
end;
LogServerEvents('We break IO loop');
finally
SocketStream.Free;
end;
except
on e: exception do
LogError('Error: '+e.Message);
end;
end;
-
> Тобишь 1 или 17?
Читай ровно столько, сколько осталось прочитать из этих 17-ти ожидаемых байт
запросил к чтению 17, фактически прочитал 2, осталось прочитать 15 запросил к чтению 15, фактически прочитал 5, осталось прочитаь 10 запросил к чтению 10, фактически прочитал 1, осталось прочитаь 9 запросил к чтению 9, фактически прочитал 4, осталось прочитаь 5
и т.д. до тех пор пока "осталось прочитаь" не станет равным 0
Эта логика применима во всех случаях, когда заранее известен размер очередного инф.сообщения, ожидаемого к приему от партнера на данном этапе исполнения протокола инф.обмена.
|