2013-11-21 30 views
3

我想投一個struct sockaddr_storage的一個sockadd_in,這樣我可以打印出數據報文的源IP地址, 我似乎沒有能夠拿到投正確的,鑄造struct sockaddr_storage的作爲有sockaddr_in爲inet_ntop

struct sockaddr_storage peer_addr; 


getnameinfo((struct sockaddr *) &peer_add 
       peer_addrlen, 
       hostbuff, sizeof(hostbuff), 
       NULL, 0, NI_NAMEREQD); 


inet_ntop(AF_INET, (((struct sockaddr_in *)peer_addr).sin_addr), ipbuff, INET_ADDRSTRLEN); 

當我試圖結構轉換爲sockaddr_in的,我要麼得到「無法轉換爲指針」,或當我刪除dereferance我得到「轉換到非請求類型定標器」。

我已經嘗試了很多組合,根本不明白我去哪裏錯了。

回答

9
inet_ntop(peer_addr->ss_family, &(((struct sockaddr_in *)peer_addr)->sin_addr), ipbuff, INET_ADDRSTRLEN); 

應該工作。但考慮到使用getnameinfo()代替,這是更現代的 接口:

char host[NI_MAXHOST]; 
getnameinfo((struct sockaddr *)peer_addr, peer_addr->ss_len, host, sizeof(host), NULL, 0, NI_NUMERICHOST); 

同時適用於IPv4和IPv6地址。


更新根據變化的類型的問題:這是一個完整的例子 應該編譯沒有警告:

int socket = ...; 

struct sockaddr_storage peer_addr; 
socklen_t peer_addrlen; 
char host[NI_MAXHOST]; 

ssize_t amount; 
char buffer[1000]; 
amount = recvfrom(socket, buffer, sizeof(buffer), 0, (struct sockaddr *)&peer_addr, &peer_addrlen); 
getnameinfo((struct sockaddr *)&peer_addr, peer_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST); 

或者,使用inet_ntop()

char ipbuff[INET_ADDRSTRLEN]; 
inet_ntop(peer_addr.ss_family, &(((struct sockaddr_in *)&peer_addr)->sin_addr), ipbuff, INET_ADDRSTRLEN); 
+0

我想getnameinfo()返回的地址的主機名? – Babbleshack

+0

@Babbleshack:請參閱NI_NUMERICHOST標誌的「man getnameinfo」:以數字形式返回地址,如同調用inet_ntop(3),而不是主機名。 –

+0

謝謝,對不起,其如此明顯!生病現在嘗試。 – Babbleshack

2
struct sockaddr_storage * peer_addr; 


getnameinfo((struct sockaddr *) &peer_add 
       peer_addrlen, 
       hostbuff, sizeof(hostbuff), 
       NULL, 0, NI_NAMEREQD); 

在這裏你正在混合的東西。

getnameinfo()確實需要struct sockaddr*作爲第一個參數,但你嘗試在這裏做什麼都不行:peer_addrstruct sockaddr_storage *,你把它的地址 - 這是一個struct sockaddr_storage **,並嘗試施放此。這是行不通的。

我不知道你的peer_addr從何而來,但

  • 要麼它應該是一個struct sockaddr_storage(我不認爲有必要有一個指向struct sockaddr_storage某處)
  • 或者它確實是一個指針,並且您應該通過(struct sockaddr *) peer_addr - 不帶& - 至getnameinfo()

另一點:getnameinfo()的第二個參數應該是您輸入的地址結構的「真實」大小。

+0

當我嘗試這樣做時,我得到一個編譯錯誤,當我使用我的原始代碼時,我的程序按預期工作。 這是否意味着我有'未定義的行爲' – Babbleshack

+0

@Babbleshack我不知道這是什麼測量,因爲我不知道你得到了哪個編譯錯誤。但很有可能你會得到UB,因爲演員可能隱藏和隱藏問題。 – glglgl

+0

當我從sockaddr中刪除了這個錯誤時,我得到'轉換爲非縮放器類型'的錯誤 – Babbleshack