2010-03-14 29 views
0

我们在Indy10中遇到了一个奇怪的问题,那就是我们使用TCP一个接一个地发出两个大字符串(每个数字为几百个字符)出现在另一端奇怪地交织在一起。这种情况极少发生。使用Indy收到的奇怪的罕见乱序数据

每个字符串都是以LF结尾的完整XML消息,并且通常READ过程读取整个XML消息,当它看到LF时返回。

实际发送消息的调用受到关于IOHandler的writeln方法调用的关键部分的保护,因此两个线程不可能同时发送。 (我们确定关键部分已经实施/正常工作)。这个问题很少发生。症状很奇怪......当我们发送字符串A后跟字符串B时,我们在另一端(在我们失败的罕见情况下)收到的是字符串A本身的尾部(,有一个LF在它的结尾处),然后是字符串A的前导部分,然后是整个字符串B,后面跟着一个LF。我们已经验证了“超时”属性在部分读取后不是真的 - 我们在每次读取内容后都会记录该属性。此外,我们知道字符串中没有嵌入的LF字符,因为在追加LF并发送它之前,我们用空格替换了字符串中的所有非字母数字字符。

我们在传输和接收端的关键部分都有日志机制,所以我们可以在“wire”上看到这种行为。

我们完全不知所措(尽管总是最低的可能性)是否可能存在一些可能导致此问题的低级别Indy问题,例如,缓冲区以错误的顺序发送....很难相信这可能是问题,但我们正在抓住吸管。

有没有人有任何明智的想法?

回答

2

在接收端是否有多个线程同时从同一个套接字读取?即使只是查询Connected()状态也会导致读取发生。如果你不小心,这可能会导致你的多线程读取入站数据并将其存储到IOHandler.InputBuffer中。

+0

我们对代码进行了一些重构,然后升级到最新的Indy10(Tiburon分支),问题没有复发。我不认为有任何线程问题,因为有一个线程的任务是完成所有读取操作,然后将接收到的数据放置在线程安全队列中供其他应用程序访问。不过,我会再次检查代码以解决潜在的线程问题。 – Jim 2010-08-03 12:36:57

+1

如果您有唯一的线程完成所有的读取操作(包括所有Connected()调用),那么Indy可以按顺序接收数据的唯一方法是发送方将数据从头开始发送。 – 2010-08-03 18:05:13

3

您使用的是TCP还是UDP?如果您使用的是UDP,则有可能(并且预期)由于通过网络进行路由,UDP数据包的接收顺序可能与它们传输的顺序不同。如果是这种情况,则需要为每个UDP数据包添加一些数据包ID,以便接收方可以正确定购数据包。

+0

应该提到它是TCP。我编辑了这个问题。 – Jim 2010-03-14 12:32:37

4

您可以试试Wireshark以了解数据如何传输。这样你就可以发现问题出在服务器还是客户端。还请记住使用TCP以正确的顺序获得“有保证的”有效数据。

2

您是否检查过IOHandler的Nagle设置?我们有一个类似的问题,我们通过将UseNagle设置为false来解决这个问题。在我们的案例中,由于Nagle合并发送和接收大量的突发数据的速度很慢,因此与您的情况并不完全相同。