2015-01-16 97 views
2

有一个令人讨厌的线程(客户端)正在等待来自远程设备(服务器)的事件。事件通过专用网络的TCP套接字接收(我必须分配静态IP)。该操作不是阻塞操作,而是轮询(select + recv)。对于某个操作,线程使用CURL库开始与设备的FTP传输。然后,有时,而不是下一个正常操作,我们正在接收垃圾。该行为可以在三台计算机中的两台上系统地再现。如果设备通过网络端口直接连接,则其中一个适用,但如果通过网络USB适配器(允许Internet连接)则不适用。另一方面,适配器在这种情况下在另一台计算机上工作得很好。 如果我们消除FTP传输,一切正常。该行为与使用的CURL版本和最后一个7.40相同。套接字接收错误的数据并发FTP传输

我是一个维护者,这里有一个古老的巨型项目,我几乎无法改变/重写东西,特别是在这种情况下,这段代码显然工作了几年(尽管有些问题已经发出)差不多两个月前。但是我必须解决这个问题,并且如果有必要,我会将操作从轮询更改为阻止,例如。其他同事已经看到了代码,Application Verifier没有检测到任何东西,从recv收到的缓冲区已经损坏,Wireshark说我们正在接收正确的数据包 - 什么都没有!调试有点困难,因为这个庞大的“应用程序”没有调试设置,并且通过远程调试和一些“精心挑选的”断点......错误的行为消失了。我尝试了大部分平常(过去获胜)的路径将近两周,其余的看起来并不太有希望 - 而且都需要时间:1)直接调试其中一台电脑(如果调试可复制,安装VS之后,从服务器获取完整的代码) - 我不知道还有什么可以尝试2)编写“正确的”代码在单独的项目中完成(已经以某种方式启动)3)另一种llvm构建(巨大的努力)。

任何想法是赞赏,我会很高兴对任何澄清要求作出反应。

编辑 我们在最小的测试程序中重现了这种情况。它发生在三个尝试过的两台电脑上的USB网络适配器上。 我们通过TCP套接字从我们的设备获得两个命令。我们只读第一个(1字节),我们使用CURL库进行FTP传输,然后读取另一个(7字节),但只有垃圾。如果我们通过读取第二个命令来切换FTP呼叫,那么即使在无限循环中,一切都很好。 Wireshark显示数据(7字节)正确,因此CURL FTP传输过程中发生的事情很明显。但是它如何影响不相关的套接字呢? 当前步骤是确定损坏我们的套接字的CURL调用。

编辑2 我们没有准确地识别脏CURL调用,因为它不是一个固定点。我们通过recv(..., MSG_PEEK)和跟踪来完成这个识别,有时它可以在两个printf指令之间,尽管它在相同的代码区域附近。恕我直言,这是唯一可能的,因为一些CURL连接调用产生另一个线程(命名为[email protected],显然在Windows内部使用),可能会改变我们的套接字堆栈。通过在一些地方添加Sleep(1500) ...它的工作原理。与64位版本相同的“不工作”行为。虽然它从来没有与CURL一起工作,用FtpGetFile取代它,但它的工作原理与第一次呼叫的例外...... :(我的想法是“D-Link DUB-E100 USB 2.0快速以太网适配器”有一些在其驱动程序中出现严重问题(最新,Windows 7版本与Vista版本相同,BTW)。解决方法似乎是先读取套接字上的通知,然后处理它们。或者也许只是使用另一个线程来完成FTP工作。

+0

“另一方面,适配器工作得很好,在这种情况下,在另一台计算机上” - 可能值得研究一下计算机,它适用于两者不同的计算机,例如网络驱动程序版本,病毒软件,固件版本,防火墙配置等等。 –

+0

当前的过程是比较计算机上的日志(内部,Wireshark),我们确定了这两种行为:它通过直接连接工作,而不是由适配器工作。 – Liviu

+0

@HarryJohnston Windows防火墙可能是一个想法,即使我无法看到它如何以这种方式影响行为。有趣的是,只有工作的电脑才有杀毒软件。 – Liviu

回答

1

这是一个罕见的问题,其中问题确实是其他人代码中的错误; OP已经确认以太网设备驱动程序有故障。