2015-01-16 95 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已經確認以太網設備驅動程序有故障。