2009-04-12 12 views
8

我試過如下:聽(),而不調用bind()

int sockfd = socket(...); 
listen(sockfd, 10); 
accept(sockfd, ...); 

的呼叫沒有失敗,該計劃剛開始阻止我彷彿被稱爲綁定()。在這種情況下會發生什麼?由於它沒有本地地址或端口,會不會收到連接?還是隱式地分配了一個本地地址和端口,現在它正在監聽這些地址?如果是這樣,我如何檢索這些是什麼?

回答

10

這些調用正在工作,但由於您沒有明確地綁定套接字,因此操作系統或系統庫爲您隱式地分配了一個端口和默認綁定(與在調用connect(2)時未調用bind(2)時完全相同)。另外,既然你問有關TCP東西前,我假設你在談論互聯網插座在這裏。

找出操作系統綁定套接字的名稱因操作系統而異,因此您必須查找特定的操作系統,但大多數操作系統提供了一個netstat或類似的工具,您可以使用它來查詢哪些應用程序正在偵聽

正如約翰在評論中提到的那樣,您可以使用getsockname(2)來查找綁定套接字的名稱。下面是一個簡單的例子:

// ... 

// Create socket and set it to listen (we ignore error handling for brevity) 
int sock = socket(AF_INET, SOCK_STREAM, 0); 
listen(sock, 10); 

// Sometime later we want to know what port and IP our socket is listening on 
socklen_t addr_size = sizeof(struct sockaddr_in); 
struck sockaddr_in addr; 
getsockname(sock, (struct sockaddr *)&addr, &addr_size); 

addr現在將包含IP地址和端口,您的套接字正在監聽。

+0

的getsockname()調用會給你的OS分配的地址/端口。 – 2009-04-12 14:34:46

0

我懷疑你永遠不會得到連接。在運行程序之前和之後,您可以通過在您的操作系統上執行相當於「netstat -an」的操作來檢查是否有新的套接字正在偵聽。

我想在C#中同樣的事情:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
socket.Listen(1); 
socket.Accept(); 

我得到它告訴我在一個綁定需要迂迴的方式,第二線的異常。這當然工作正常:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
socket.Bind(new IPEndPoint(IPAddress.Loopback, 4567)); 
socket.Listen(1); 
socket.Accept(); 

我有一個UDP套接字以及和一回事測試中,Windows是不開心的聽着叫除非綁定已經完成。由於.Net套接字調用僅僅是Winsock的包裝,所以對於Windows上的所有Winsock派生庫,這種行爲可能都是相同的。

2

正如其他人提到的,如果您不綁定(),操作系統將分配一個端口。您可以使用getsockname()電話後聽(),看看有什麼地址/端口分配。然後,如果您將該地址/端口傳達給客戶端,則可以連接。

所以這是有道理的,這是有效的。你可以寫一個程序,這是一件很有趣的事情。