2013-04-04 200 views
2

我有服務器和客戶端程序用C編寫,工作正常,但我無法找出下面解釋的行爲的原因:服務器和客戶端顯示的公共端口號不同端口號

server.c

server_address.sin_family = AF_INET; 
server_address.sin_port = htons(9374); 
server_address.sin_addr.s_addr = htonl(INADDR_ANY); 
server_len = sizeof(server_address);  
bind(server_sockfd, (struct sockaddr *)&server_address, server_len); 

getsockname (server_sockfd, (struct sockaddr *)&server_address, &server_len); 
printf("server port = %d\n", server_address.sin_port); 
printf("Server Waiting......\n"); 
listen(server_sockfd, 5); 

client.c

address.sin_family = AF_INET; 
address.sin_port = htons(9374); 

int length, result; 
length = sizeof(address); 

result = connect(sockfd, (struct sockaddr *)&address, length); 

getsockname(sockfd, (struct sockaddr *)&address, &length); 
printf("Connecting to Port = %d \n", address.sin_port); 

個輸出服務器端:

[[email protected] Socket]# ./server 
server port = 40484 
Server Waiting...... 

在客戶端輸出:

[[email protected] Socket]# ./client 
Connecting to Port = 18576 

我的問題是:

雖然相同的端口號(9374)和操作在服務器和客戶端代碼執行,但爲什麼他們顯示不同的端口號(例如服務器上的40484和客戶端上的18576)?

+0

簡短的回答 - 你連接到一個已知的端口,你的sessio n被分配給其他未使用的端口。檢查接受和連接手冊頁,或嘗試http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html beej非常可讀,幾乎幽默。 – 2013-04-04 19:14:44

回答

3

getsockname()返回連接的本地端口號。 TCP連接有兩個端口,連接的每一端都有一個端口。

由於您的客戶端尚未調用bind()來選擇本地端口,因此係統會隨機爲您選擇一個端口。

因此,您的服務器程序正在顯示它正在監聽的自己的端口,並且您的客戶端會顯示它自己的端口。

還請注意,您在網絡端格式打印出來的端口號,打印出來在主機端,使用ntohs和()這樣的(和客戶端上類似)

printf("server port = %d\n", ntohs(server_address.sin_port)); 

這將使服務器打印出來9374

如果你想獲取客戶端的服務器端口,請使用getpeername()而不是getsockname() - 然後再次,您已經知道服務器端口,因爲那是您連接到的端口9374。

+1

@Mike如上所述,TCP連接涉及2個端口。作爲客戶端,您需要將本地端口連接到遠程端口。遠程(服務器)端口通常是衆所周知的端口,例如80用於HTTP。本地端口通常無關緊要,因此讓系統選擇一個可用的隨機端口非常有用。 – nos 2013-04-04 19:30:12

+0

感謝它幫助。 -Jay – Jayzcode 2013-04-05 09:47:22