2016-10-13 14 views
0

我試圖製作一個接受連接的非常簡單的服務器。sockaddr.sin_port = 1337與「真實」打開的端口不匹配

int sock, serv; 
struct sockaddr_in in_sock; 
serv = socket(AF_INET, SOCK_STREAM, 0); 
in_sock.sin_addr.s_addr = 0; 
in_sock.sin_port = 1337; 
in_sock.sin_family = AF_INET; 
bind(serv, (struct sockaddr *)&in_sock, sizeof(in_sock)); 
listen(serv, 0); 
client = accept(serv, 0, 0); 

但是嘗試連接到127.0.0.1:1337的時候,我得到一個連接被拒絕的消息:

(未知)[127.0.0.1] 1337(?):連接被拒絕

然而一個簡單的netstat -tcpan讓我發現,一個端口被打開確實:

TCP 0 0 0.0.0.0: 14597 0.0.0.0:* LISTEN

如果我將sin_port設置爲更高的端口,它似乎可以正常工作。

缺少什麼我在這裏?爲什麼不打開1337端口?它似乎也是免費的。

+0

你必須使用['htons'(https://linux.die.net/man/3/htons)的端口連接到交換機的字節順序 –

回答

3

struct sockaddr_in中的端口號字段以網絡字節順序存儲。這意味着存儲的值,就當你必須使用htons()

in_sock.sin_port = htons(1337); 

否則,端口號將保留字節交換。這正是這裏發生了:

1337 = 0x0539 
14597 = 0x3905 
+0

這很有趣,我認爲這可能是問題,我應該更深入地研究它。非常感謝,這是問題所在。 – user96649

1
listen(serv, 0); 

的第二個參數是listenbacklog如果我們看一下documentation for listen

積壓參數定義的最大長度,其用於的sockfd 未決的連接隊列可以生長。如果連接請求 在隊列滿時到達,則客戶端可能會收到錯誤 指示ECONNREFUSED,或者如果基礎協議支持 重新傳輸,則該請求可能會被忽略,以便稍後在連接中重新嘗試 成功。

ECONNREFUSED正是您收到的錯誤消息,因爲積壓已滿(它可以保持0個連接,因此它總是已滿)。 您應該將該數字增加到至少1,但更高的數字可能會更好listen(serv, 10);

+0

好,但是爲什麼我可以連接到netstat顯示的端口?因此,端口在正確的地址打開,向我發送ECONNREFUSED,但另一個在錯誤的端口打開,但我可以連接到它? – user96649