有一个令人讨厌的线程(客户端)正在等待来自远程设备(服务器)的事件。事件由专用网络通过TCP套接字接收(我必须分配静态IP)。该操作不是阻止操作,而是轮询(select
+ recv
)。对于某个操作,线程使用FTP
库与设备开始CURL
传输。然后,有时候,我们正在接收垃圾而不是下一次正常操作。该行为可以系统地在三台计算机中的两台上重现。在其中一个设备上,如果设备直接通过网络端口连接,则无法通过网络USB适配器(允许Internet连接)连接。另一方面,在这种情况下,适配器在另一台计算机上运行良好。 如果我们取消了FTP传输,一切正常。行为与使用的CURL版本相同,最后一个版本为7.40。
我是维护者,这是一个古老的巨大项目,我几乎无法改变/改写事物,特别是在这种情况下,这段代码显然已经工作了好几年(尽管有些问题已经发出信号)并且在测试前差不多两个月。但是我必须解决这个问题,如果需要,我会将操作从轮询改为阻塞。其他同事已经看到了代码,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连接调用会生成另一个可能改变套接字堆栈的线程(名为_SockAsyncThread@4
,显然是Windows内部使用)。通过在某些地方添加Sleep(1500)
......它可以正常工作。同样的"不工作" 64位版本的行为。虽然它永远不能与CURL一起使用,但是用FtpGetFile
替换它,它在第一次调用的例外情况下工作:(。我的想法是" D-Link DUB-E100 USB 2.0快速以太网适配器"在其驱动程序中存在一些严重问题(最新版本,Windows 7版本与Vista版本相同,BTW)。在我看来,首先在我的套接字上读取通知,然后处理它们。或者只是使用另一个线程来完成FTP工作。
答案 0 :(得分:1)
这是一个罕见的问题,其中问题确实是别人的代码中的错误; OP确认以太网设备驱动程序有故障。