2017-01-06 48 views
4

我有一個關於C.accept()函數是如何工作的?

accept()功能問題,當服務器接收的連接時,accept()函數創建一個新的socket與客戶進行溝通,然後讓「老套筒」偵聽新的連接。然後,我知道服務器可以通過「新套接字」與客戶端通信,但客戶端如何與「新套接字」進行通信(因爲客戶端不知道這個「新套接字」) ?

+0

客戶端在服務器使用socket()知道它之前創建了「新套接字」,並用'connect()指向服務器。注意:二進制「套接字ID」表示可能在不同物理機器上的不同進程中的不同內存位置。 – ebyrob

+0

客戶端也不知道* old *套接字。 –

回答

6

在服務器端,監聽套接字僅與一個本地IP和端口相關聯,並且是處於LISTEN狀態。

相反,接受了服務器上的插座(以及在客戶端上連接的插座)由本地IP地址和端口,以及一個遠程IP地址和端口被識別並處於ESTABLISHED狀態。

在客戶端,也沒關係,該服務器使用一個監聽套接字從連接的插座分開。當客戶端從connect返回時,服務器從accept返回,並且從每個返回的套接字描述符可以相互通信。

+0

那麼服務器中的多個套接字是否可能在同一個本地端口上運行?它們是通過遠程地址和端口來區分的嗎? – Milack27

+1

@Milack這是正確的。監聽套接字可以多次調用「accept」接受多個連接。所有這些被接受的套接字將具有相同的本地IP和端口,但遠程IP和/或端口將有所不同。 – dbush

+0

好吧,我明白了。但是,在connect()(在套接字「sock」)上返回後,如果客戶端在同一個套接字(「sock」)上寫了一些東西,那麼客戶端接受的套接字與「new套接字「用accept()創建?我的意思是,客戶端如何自動在使用accept()創建的套接字上寫入? – Masiwan

1

套接字是網絡編程API的抽象。在連線和客戶端上,仍然只有一個連接,並且客戶端不會看到服務器是否正在使用具有listen,accept等的網絡API,或者服務器是否使用其他API或原始套接字來建立連接。

0

的解釋是,一個TCP(在TCP/IP傳輸的終點)唯一地由一對名稱IP地址/端口號來標識。當客戶請求連接時,它使用它的IP和端口號進行連接,這是唯一的一對。該操作將SRCIP + SRCPORT綁定到DSTIP + DSTPORT,這4個數字(兩個IP加上兩個端口)唯一標識一個連接。所以服務器上的兩個套接字確實指向兩個不同的連接/流。

2

IP協議(包括TCP/IP)中的任何通信都發生在兩個端點之間。端點始終是主機:端口。在TCP世界中,兩個端點識別連接。套接字與連接關聯,而不是與端點關聯。

因此,你可以有2返回接受2個插座()調用,描述了兩個不同的連接。

這裏是netstat -an輸出在UNIX機器上的一個例子:

tcp  0  0 0.0.0.0:22     0.0.0.0:*     LISTEN 
tcp  0  0 170.44.26.7:22    161.231.133.178:11550  ESTABLISHED 
tcp  0  0 170.44.26.7:22    161.231.133.178:33938  ESTABLISHED 
tcp  0  0 170.44.26.7:22    161.231.133.178:13875  ESTABLISHED 
tcp  0  0 170.44.26.7:22    161.231.133.178:34968  ESTABLISHED 
tcp  0  0 170.44.26.7:22    161.231.133.178:44212  ESTABLISHED 
tcp  0  0 170.44.26.7:22    161.231.133.178:34967  ESTABLISHED 

在這裏,我們有一個監聽套接字,和幾個連接(通過其自身的插座每個支持)從accept()套接字上產生。