2011-09-26 70 views
1

我寫一個服務器 - 客戶端程序,並在服務器中我使用getaddrinfo和getsockname在服務器上,以獲取有關本地IP地址和本地綁定端口號的信息返回。 使用此信息,我啓動我的客戶端程序並使用getaddrinfo,然後僅打印出servinfo數據結構中的返回值: getaddrinfo(argc [1],argc [2],&提示,& servinfo); >>服務器主機名和服務器端口號通過命令行傳遞。sin_port中的getaddrinfo錯誤

但我注意到,在servinfo的sin_port是不是我通過命令行傳遞的端口。 1)這個getaddrinfo是否返回客戶端使用的端口號作爲源端口號? 2)getaddrinfo和套接字調用失敗後,我的連接調用。我不知道爲什麼。我如何調試它?

我的客戶代碼片段:

memset(&hints, 0 ,sizeof hints); 
hints.ai_family = AF_INET; 
hints.ai_socktype = SOCK_STREAM; 
hints.ai_flags = AI_CANONNAME | AI_NUMERICSERV; 
getaddrinfo(argc[1], argc[2], &hints, &servinfo); 

for (p = servinfo till p!=NULL) 
    sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol) 
    connect(sockfd, p->ai_addr, p->ai_addrlen) >>>>> Connect not going through. 

我開始了我的客戶端程序是這樣的: ./a.out myservername 18844個

謝謝!

+0

你怎麼知道的getaddrinfo()沒有失敗,錯誤?你沒有檢查它的返回值是否爲零。如果gettaddrinfo()失敗,那麼它當然不會寫入數據到它的輸出參數。 –

+0

我正在用servername調用它。但錯過了將它添加到問題描述中。 – Vin

+0

我將檢查getaddrinfo的返回碼。它不應該失敗,因爲我能夠讀取以servinfo結構返回的IPv4地址。 – Vin

回答

4

新的答案:你只使用一個參數調用程序,所以argv[1]包含"18844"argv[2]是一個空指針。這將試圖連接到一個數字IP 18844的主機和一個未指定的端口號(最終將爲0並失敗)。

老答案:(相關,但不是你的問題)sin_port和整個sockaddr_in結構是網絡字節順序。你需要的端口轉換與ntohl使用它作爲一個數字,但你會過得更好從來沒有接觸sockaddr結構內部任何責任。相反,使用getnameinfoNI_NUMERICHOSTNI_NUMERICSERV得到返回的地址到一個基於字符串的數字形式,然後strtol讀端口(「服務」)數量爲整數。即使對於非IPv4網絡地址/協議族(如IPv6)也是如此,並且不需要額外的代碼來支持新的代碼。

+0

更不用說'argc'不是通常用於'argv'數組的名稱。 –

+0

我會嘗試。但是,sin_port是客戶端端口嗎?還是應該與我通過命令行傳遞的服務器端口相同?對不起,我很困惑。 – Vin

+0

您通過P-> ai_addr連接(),所以它會被用作地址,*連接到*,服務器的地址。如前所述,通過strace運行你的代碼,你會看到connect()被調用的參數。 – nos

相關問題