缺少来自indy TCPServer的数据。德尔福XE2

时间:2015-07-10 08:03:10

标签: delphi indy tcpserver

我有一个使用TIdTCPServer的应用程序。我发送空终止消息到服务器(Delphi XE2,随附它的Indy包)成功地作为空终止字符串。 OnExecute过程如下:

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;

我的问题是,如果我发送了大量的消息,如果我没有在消息之间放置200毫秒的延迟,那么我就会丢失数据。

没有延迟: 我要么完全丢失数据(从107发送的13条消息)和/或数据不正确: < 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%

以粗体显示的事件是缺少数据。

我也看到了与TIdUDPServer组件相同的行为。我看到的唯一区别是,对于UDP,正确接收所有数据所需的延迟是100 ms,而对于TCP服务器,消息之间的延迟小于200 ms总是导致数据丢失。 对于发送到Windows事件服务的UDP,因此事件出现在相应的Windows日志中,不需要延迟,我可以正确地看到所有事件。

谢谢, 杰夫考克斯

1 个答案:

答案 0 :(得分:0)

您显示的TIdTCPServer代码不是从套接字读取以空值终止的消息。它只是简单地读取发生的原始数据,以便在特定时刻出现在套接字上。此时可能没有消息,或者可能存在完整消息,或者可能存在多个消息的部分消息。这就是TCP的工作原理。

如果您的消息真正以空值终止,则需要通过等待空终止符到达然后处理它之前的任何内容来读取它们。例如,您可以使用TIdIOHandler.ReadLn()TIdIOHandler.WaitFor()方法实现此目的:

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;
相关问题