2014-11-16 102 views
1

網絡編程noob在這裏,套接字API:爲什麼`connect`不返回描述符?

我很困惑的行爲acceptconnect套接字函數。在大多數編程語言中,這些函數的包裝返回不同類型的值:accept返回一個新的描述符,我們可以使用它來發送/接收數據,但connect不返回任何內容(或返回錯誤代碼)。

對我來說,看起來像connect也應該返回一個描述符。它們都在兩個套接字之間打開一個通道,但只有其中一個功能返回與遠程套接字進行通信的有用信息。

這會影響我構建程序的方式。例如,我可以很容易地產生一個新的工人/線程/等。對於每個傳入的連接,但對於我使用connect創建的每個連接都不是很容易,因爲在這種情況下我沒有新的描述符(所以我不能使用recvsend而不做一些簿記)

任何人都可以解釋我爲什麼這樣工作?

我想原因是,由於socket包裝的編程語言遵循BSD API緊密合作,並在這種情況下,我的問題是:爲什麼BSD套接字以這種方式工作?當前的實現會導致不必要的複雜程序或冗餘套接字。我要麼需要做更多的簿記(導致更復雜的程序),要麼爲每個出站連接創建一個新的套接字(導致冗餘套接字)。

謝謝。

回答

2

connect()將現有描述符作爲輸入。您先創建並配置描述符,然後再將其配置到服務器。所以不需要它返回一個新的描述符,因爲你必須事先創建描述符。

accept()也將現有描述符作爲輸入,但該描述符表示偵聽套接字。當客戶端被接受時,需要一個唯一的描述符來讀/寫這個特定的客戶端,這個監聽描述符不能用於那個,所以accept()返回一個新的描述符。

你不需要以不同的方式構建你的線程。在客戶端,在connect()之後,向服務器派生一個線程併爲其提供已連接的描述符。在服務器端,客戶端產生一個線程併爲其提供被接受的描述符。在這兩種情況下,線程只需關心要操作哪個描述符,而不是描述符來自哪裏。兩個線程都可以根據需要使用recv()send(),然後使用close()完成描述符的使用。

您不能重新使用套接字描述符進行新連接(當然,Windows上的WinSock2具有非標準的擴展來允許這樣做,但該功能並不常用)。連接斷開後,其描述符必須關閉。無論何時需要創建新的連接,您都必須創建新的描述符。