来自 indy TCPServer 的数据丢失。 Delphi XE2
Missing data from indy TCPServer. Delphi XE2
我有一个使用 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 条消息)and/ot 数据不正确:
<38>7 月 10 09:37:39 cilad71 QJRN:ope=作业已更改 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>7 月 10 日 09:37:39 cilad71 QJRN:ope=作业已更改 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 毫秒,而对于 TCP 服务器,消息之间的延迟小于 200 毫秒总是会导致数据丢失。
对于 UDP,当发送到 Windows 事件服务时,事件出现在相应的 Windows 日志中,不需要延迟,我正确地看到了所有事件。
谢谢,
杰夫·考克斯
您显示的 TIdTCPServer
代码不是从套接字读取以 null 终止的消息。它只是读取 happens 在那个特定时刻出现在套接字上的任何原始数据。在那一刻可能没有消息,或者可能有一条完整的消息,或者可能有多条消息的部分片段。这就是 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;
我有一个使用 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 条消息)and/ot 数据不正确: <38>7 月 10 09:37:39 cilad71 QJRN:ope=作业已更改 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>7 月 10 日 09:37:39 cilad71 QJRN:ope=作业已更改 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 毫秒,而对于 TCP 服务器,消息之间的延迟小于 200 毫秒总是会导致数据丢失。 对于 UDP,当发送到 Windows 事件服务时,事件出现在相应的 Windows 日志中,不需要延迟,我正确地看到了所有事件。
谢谢, 杰夫·考克斯
您显示的 TIdTCPServer
代码不是从套接字读取以 null 终止的消息。它只是读取 happens 在那个特定时刻出现在套接字上的任何原始数据。在那一刻可能没有消息,或者可能有一条完整的消息,或者可能有多条消息的部分片段。这就是 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;