2011-10-24 70 views
3

我做了一個實驗:
服務器偵聽端口8804接受客戶端的連接,然後發送數據給客戶端。我關閉了網絡。連接超時TCP寫入(netstat顯示ESTABLISHED)

  1. 當我運行netstat -anotp | grep 8804,它表明服務器和客戶端的連接都是「ESTABLISHED」,但沒有數據傳輸。
  2. 過了一會,服務器拋出一個錯誤:「連接超時」
  3. netstat -anotp | grep的8804,發現客戶仍然是「ESTABLISHED」

所以:
1.爲什麼被屏蔽的系統調用的服務器「寫」扔「連接超時」的錯誤。爲什麼不是客戶?
2.如何讓客戶端找到連接實際上是關閉的。
3.當網絡不工作時,爲什麼服務器和客戶端的狀態都是「ESTABLISHED」?

感謝您的回答!

+1

你有什麼語言在這個問題? –

+0

@Mike Pennington,C – renenglish

回答

6
  1. 您的服務器需要爲其發送給客戶端的單個數據段的TCP ACK;然而,客戶端不知道服務器的數據有多長。由於您關閉網絡,服務器不再從客戶端獲取ACK。結果:服務器上的連接超時(請參閱注1)
  2. 在您的套接字上使用TCP Keepalive(請參閱注2)
  3. 您尚未啓用TCP Keepalives。如果您正在使用python,你可以這樣做(假設你的插座被命名爲s):
# Do this before you accept() anything on the socket 
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) 

編輯:
由於您使用的C,鏈接到Linux TCP Keepalives Howto

NOTES
1. RFC 1122: Section 4.2.3.5 "TCP Connection Failures"
2. RFC 1122: Section 4.2.3.6 "TCP Keepalives"

+0

Mike,+1,但「客戶不知道服務器數據的時間長短」是什麼意思? – EJP

+0

@EJP,謝謝......我指出,當他的服務器啓動一個「無盡的」數據傳輸到客戶端時,它被動地必須等待來自服務器的EOF,並且沒有一定的keepalive機制,它會等待長時間。用kepalives,它會等待下一個段或EOF的時間。我當然可以在上面解釋它做得更好。 –