2010-06-15 78 views
1

我在Linux(homework)中實現了一個類似於FTP的協議,並且遇到了以下問題:客戶端可能能夠在連接()和寫入()之前另一方設法接受()(但在聽過()之後)。我怎樣才能防止寫操作不依賴像「接受成功,現在可以寫入」這樣的消息傳遞到另一個通信渠道?防止在對方接受請求之前寫入套接字

回答

4

直到TCP連接建立後,connect()調用纔會返回。直到服務器端調用accept(),數據纔會到達服務器應用程序。但是,一旦TCP連接建立,客戶端可能開始發送數據。它將被服務器堆棧緩衝,直到它被服務器應用程序讀取。

防止寫入操作的目的是什麼?如果服務器在調用accept()時被延遲,TCP窗口機制將暫停數據流。

+0

我確實檢查了返回值,還有這個Q3.3:http://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-3。html 它適用於UNIX,但我也有一個嘮叨的疑慮,它也適用於Linux – EpsilonVector 2010-06-15 17:11:42

+1

@EpsilonVector:握手完成後,客戶端可能會開始傳輸。它將被服務器堆棧緩衝,直到服務器應用程序從accept()返回並開始讀取。你是否看到某種問題,或者你是否謹慎? – 2010-06-15 17:21:26

+0

現在我知道有緩衝,沒有理由再停下來。它也看起來像我的問題可能與這個線程的主題無關,所以我會跟着其他線索。不管怎麼說,還是要謝謝你。 – EpsilonVector 2010-06-15 17:35:30

1

看一下TCP三次握手在時間方面:

從客戶端到服務器
  • T1
  • 由服務器收到客戶端發送
    1. SYNT2
  • SYN-ACK從服務器到客戶端
    • T3
    • 由服務器發送的T6
  • 接收由客戶端在 T4
  • ACK從客戶端到服務器
    • 由客戶端發送在T5
    • 由服務器接收的

      阻塞上在T5客戶端返回connect(2),而在阻斷T6accept(2)回報,T5嚴格小於T6。所以是的,這是客戶端可以開始發送數據的時間窗口,認爲連接已建立。如果客戶端ACK丟失,服務器卡在accept(2)中。這與阻止select(2)/accept(2)組合的知名競賽類似。

      如果服務器沒有發送任何東西,您無法真正阻止客戶端在accept(2)返回之前發送。

      解決的辦法是使服務器套接字無阻塞依靠select(2)/poll(2)/epoll(4)

  • 相關問題