2017-04-10 182 views
1

我測試一些C代碼,我發現用TCP套接字調用奇怪的行爲會發生什麼。TCP:當客戶端連接,發送數據和斷開連接之前接受

  1. 我定義它接受客戶同步並接受客戶端它處理它在for循環中,直到它斷開連接後一個監聽線程。因此,一次只能處理一個客戶。所以我在一個循環中調用accept,然後在內部循環中調用recv,直到收到一個空的緩衝區。

  2. 我火5個線程與客戶,我叫connectsend最後close

  3. 我在任何呼叫沒有錯誤。一切似乎都很好。

然而,當我打印接收服務器端的消息事實證明,只有第一個客戶端撥通了服務器,即accept永遠不會觸發其他客戶端上。

所以我的問題是:

  1. 不應該connect等到服務器調用accept?或者內核層是否照顧了引擎蓋下的緩衝區?
  2. 如果不是的話,那麼不應該在服務器能夠無論如何接受插座,即使它處於斷開狀態?我的意思是預計會失去所有傳入的數據?
  3. 或者我應該假設我的代碼中存在一個錯誤?
+0

記住'聽(INT FD,INT積壓)'第二個參數網絡互聯?在accept()將fd傳遞給用戶空間中的服務器之前,整個3way握手完成(通過TCP堆棧)。所以:套接字處於連接狀態,但用戶進程還沒有選擇它(通過調用accept()) – joop

+0

@joop右。我現在明白了。所以數據被緩衝了。我沒有看到輸出的原因是因爲我偶然鎖定了服務器。所以,謝謝你回答我的問題1.我已經知道答案2。 – freakish

+0

@joop你可能想寫它作爲答案,所以我可以接受它。 – freakish

回答

1

TCP狀態機執行同步舞蹈與客戶端的狀態機。所有這些都在OS級執行(TCP/IP 堆棧);用戶空間進程只能做一些系統調用來影響這個機器。一旦客戶撥打listen()這臺機器就開始了;並建立新的連接。

記住listen(int fd, int backlog)第二個參數?在accept()將fd傳送到用戶區中的服務器之前,整個3way握手完成(通過TCP堆棧)。所以說:插座處於連接狀態,但用戶進程還沒有把它們撿起來,但(通過調用accept()

調用accept()將導致新的連接到由內核來排隊。這些連接功能完全正常,但顯然數據緩衝區可能會填滿並且連接會受到限制。

推薦閱讀:科默&史蒂文斯:使用TCP/IP 10.6-10.7(包含TCP狀態圖)