2011-12-19 124 views
2

我有一個C/S程序。客戶端使用套接字向服務器發送文件,在發送近似超過700k數據後,客戶端(在win7上)將收到套接字10054錯誤,這意味着由對等方重置連接。socket error 10054

服務器在CentOS 5.4上工作,客戶端是windows7虛擬機在虛擬機中運行。客戶端和服務器通過虛擬網絡接口進行通信。 命令端口(發送日誌)正常,但數據端口(發送文件)有問題。 如果是由套接字緩衝區大小的錯誤配置引起的? 如果有人能幫我檢查問題。謝謝。

我每次調用套接字發送緩衝區等於4096字節 發送(插座,緩衝區,4096,0)

CentOS的插槽配置。

#sysctl -a 
... 
net.ipv4.tcp_rmem = 4096  87380 4194304 
net.ipv4.tcp_wmem = 4096  16384 4194304 
net.ipv4.tcp_mem = 196608  262144 393216 
net.ipv4.tcp_dsack = 1 
net.ipv4.tcp_ecn = 0 
net.ipv4.tcp_reordering = 3 
net.ipv4.tcp_fack = 1 

我不是很明白套接字緩衝區的配置是什麼意思,如果這樣會導致接收不完整的結果問題?

+0

「由對等方重置連接」的最可能原因是另一方崩潰的程序。 – 2011-12-19 08:32:38

+0

@David Schwartz,服務器接縫正常,套接字未關閉,最後,recv超時錯誤。 – 2011-12-19 08:34:49

+0

*接收*超時? TCP通常不會收到超時。這是你自己的代碼嗎?當你認爲收到超時時,你會怎麼做?你是否100%肯定客戶端在**服務器收到接收時間之前通過peer **重置了連接? (如果相反,這是你代碼中的一個錯誤,每一方都在等待另一方。) – 2011-12-19 08:37:48

回答

4

這幾乎肯定是你的代碼中的一個錯誤。最有可能的是,一方認爲對方超時並因此異常關閉連接。發生這種情況的最常見的方式是,您調用接收函數來獲取數據,但實際上您已經獲得了這些數據,但卻沒有意識到這一點。所以你正在等待你已經收到的數據,從而超時。

例如:

1)客戶端發送消息。

2)客戶端發送另一條消息。

3)服務器讀取這兩個消息,但認爲它只有一個,發送一個確認。

4)客戶端收到確認,等待第二個確認哪個服務器永遠不會發送。

5)服務器等待它實際上已經收到的第二條消息。

現在服務器正在等待客戶端,客戶端正在等待服務器。服務器編碼不正確,沒有意識到它實際上一次收到兩條消息。 TCP不保留消息邊界。

如果你告訴我更多關於你的協議的信息,我可以更詳細地告訴你出了什麼問題。什麼構成信息?哪邊發送什麼時候?有沒有任何確認?等等。

但短版本是,每一方可能正在等待另一方。

最有可能的是,由同級重置的連接是一種症狀。您的問題發生,一方超時並中止連接。這會導致對方重置連接,因爲另一方中止了連接。

+0

我使用socksetopt來設置recv超時。如果沒有設置超時,程序服務器將永遠等待recv並且recv不會返回。 – 2011-12-19 08:44:47

+0

啊,那麼你可能調用'recv'來等待你實際已經收到的消息。無論是你還是你的時間不夠長。或者你的協議沒有正確實施,當對方沒有理由發送消息時,你正在等待消息。但我的賭注是接收超時,然後*連接重置。所以問題是時間到了,重置是一個症狀。 – 2011-12-19 08:45:41

+0

也許這個問題與我的代碼中的接收緩衝區處理有關,我會檢查它。 – 2011-12-19 08:57:43