Я настраиваю программу клиент / сервер для отправки и получения неизвестного количества байтов в моем приложении.Как получить неизвестный размер буфера в моей программе?
Я передаю свои данные в переменную TIdBytes
и отправляю их с такой строкой:
IdTCPClient.IOHandler.Write(TIdBytes_Var);
Первый байт TIdBytes_Var
определяет размер пакета и изменяется в зависимости от других условий.Я забочусь о том, чтобы размер пакета не превышал 1024 байта.
На стороне получателя (IdTCPServerExecute) я добавляю эту строку для чтения всех байтов:
var
byte_buffer: TIdBytes;
begin
AContext.Connection.IOHandler.ReadBytes(byte_buffer,-1,false);
end;
В режиме отладки,после отправки первого пакета с клиента на сервер возникает исключение:
повышенный класс исключения EConvertError с сообщением '' 'не является допустимым значением с плавающей запятой
А в режиме работы только потеря соединения.
В чем проблема и как я могу получить все байты из входного буфера Indy?
Вот мой минимальный код:
В клиенте, создающем пакет и, наконец, устанавливающем событие, которое передается другому потоку
//create packet. Buffer_to_send is a TIdBytes variable on unit of network thread (U_network_thread).
SetLength(U_network_thread.Buffer_to_send,(6 + (tmp_ints * 12)));//set buffer lenght dynamically, tmp_ints is my record counter(shortint)
tmp_int:= 2;//tmp_int is the integer variable
U_network_thread.Buffer_to_send[0]:= $1;//header sign
U_network_thread.Buffer_to_send[1]:= tmp_ints;//tmp_ints is my record counter as short integer
while tmp_ints > 0 do
begin
Read(My_File,tmp_rec);//read record from bin file
Move(tmp_rec,U_network_thread.Buffer_to_send[tmp_int],12);//12 is record lenght
tmp_int:= tmp_int + 12; //add pointer
dec(tmp_ints);
end;
tmp_int2:= zone_i;//integer info
Move(tmp_int2,U_network_thread.Buffer_to_send[tmp_int],4); //add info to the packet
Frq_Evt.SetEvent; //set event to triger sending on other thread
На net_thread, после подключения к серверу и получения знака подтверждения с помощью команды ReadLn
, я жду события
procedure TNetThread.Execute;
.//create IdTCPClient1 and connect to server
.//receive ack from server by IdTCPClient1.IOHandler.ReadLn command
.//wait for event
while(true) do
if (FEvent.WaitFor(200) = wrSignaled) then//Buffer_to_send fill on main thread
begin
//send buff
if sending_buf(Buffer_to_send) then
begin
//sending ok
end
else
begin
//sending error
end;
end;
end;
end;
function TNetThread.sending_buf(T_Buffer: TIdBytes): boolean;
begin
try
IdTCPClient1.IOHandler.Write(T_Buffer)
result := true;
except
result := false;
end;
end;
На стороне сервера, после подключения отправляю ack sign командой WriteLn
, а на IdTCPServerExecute
пытаюсь сделать
procedure Tmain_form.IdTCPServerExecute(AContext: TIdContext);
var
byte_buffer: TIdBytes;
begin
AContext.Connection.IOHandler.ReadBytes(byte_buffer,-1,false);
//do something else
end;
Все работает нормально, соединение прошло и серверотправить знак подтверждения клирунт.Клиент получает его и ждет события.После того, как событие происходит, клиент составляет пакет и передает его net_thread.Пакет хороший и отправка тоже.Но на стороне сервера возникает проблема.