简体   繁体   中英

Missing data from indy TCPServer. Delphi XE2

I have an application that uses TIdTCPServer. I send null terminated messages to the server (Delphi XE2, Indy package which ships with it) sucessfully as null terminated strings. The OnExecute procedure is as follows:

procedure TSimpleSslServerForm.TCPServerExecute(AContext: TIdContext);
var
  RxBufStr: string;
begin
  with AContext.Connection.IOHandler do
  begin
   if not InputBufferIsEmpty then
     begin
       RxBufStr := InputBufferAsString;
       Display(RXBufStr);
       lbl_EventsReceived.Caption := IntToStr(StrToInt(lbl_EventsReceived.Caption) + 1);
     end;
   end;
end;

My issue is that if i send alot of messages, if i do not put a 200 ms delay between messages then i loose data.

Without added delay: I either loose data completely (13 messages received from 107 sent) and/ot the data is incorrect: <38>Jul 10 09:37:39 cilad71 QJRN: ope=JOB WAS CHANGED date=10/07/15 time=07:59:26 sys=CILAD71 user=GCOX job=QZSOSIGN jobn= ipadr=192.168.5.121 pgm=QZSOSIGN pgmlib=QSYS date=07/10/15 time=07:59:26 user=GCOX action=PROFILE CHANGED jobname=QZSOSIGN jobnumber=189191 jobusername=QUSER jobd=QZBSJOBD ipaddress=192.168.5.121%

07/10/15 time=08:01:25 user=GCOX action=PROFILE CHANGED jobname=QZSOSIGN jobnumber=189191 jobusername=QUSER jobd=QZBSJOBD ipaddress=192.168.5.121%

<38>Jul 10 09:37:39 cilad71 QJRN: ope=JOB WAS CHANGED date=10/07/15 time=08:01:35 sys=CILAD71 user=GCOX job=QPADEV000D jobn= ipadr=192.168.5.121 pgm=QWTPIIPP pgmlib=QSYS date=07/10/15 time=08:01:35 user=GCOX action=START jobname=QPADEV000D jobnumber=189401 jobusername=GCOX jobd=QDFTJOBD ipaddress=192.168.5.121%

The event in bold is missing data.

I see the same behaviour with the TIdUDPServer component also. The only difference i see is that for UDP the required delay to receive all the data correctly is 100 ms, whereas for the TCP server a delay of less than 200 ms between messages always results in data loss. For UDP when sending to a Windows Event service so the event appears in the corresponding Windows journal no delay is required and I see all the events correctly.

Thanks, Geoff Cox

The TIdTCPServer code you have shown is NOT reading null-terminated messages from the socket. It is simply reading whatever raw data happens to be present on the socket at that particular moment. There might be no messages at that moment, or there might be a full message, or there might be partial pieces of multiple messages. This is just how TCP works.

If your messages are truly null-terminated, you need to read them as such, by waiting for the null terminator to arrive and then process whatever precedes it. For example, you can use the TIdIOHandler.ReadLn() or TIdIOHandler.WaitFor() method for that purpose:

procedure TSimpleSslServerForm.TCPServerExecute(AContext: TIdContext);
var
  RxBufStr: string;
begin
  RxBufStr := AContext.Connection.IOHandler.ReadLn(#0);
  ...
end;

procedure TSimpleSslServerForm.TCPServerExecute(AContext: TIdContext);
var
  RxBufStr: string;
begin
  RxBufStr := AContext.Connection.IOHandler.WaitFor(#0);
  ...
end;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM