2013-08-19 62 views
3

recvfrom要求第5個參數是指向sockaddr結構的指針,第6個參數是指向socklen_t的指針。如何使用recvfrom獲得AF_INET6插槽的地址

man recvfrom (3)說:

如果地址的實際長度比 供給sockaddr結構體的長度大,所存儲的地址將被截斷。

我不明白我怎麼能檢索與AF_INET6地址族發送插座的地址自的大小大於sockaddr因此將由recvfrom截斷。

我是否知道recvfrom無法檢索大於sizeof(sockaddr)的地址?

難道我得到它的權利,即使我定義投的一個實例是地址sockaddr*並將它傳遞給recvfrom,該功能將無法知道有足夠的空間可用於存儲的地址?

回答

7

您傳遞的(型鑄造)和結構的大小作爲參數指針:

struct sockaddr_in6 in6; 
socklen_t len6 = sizeof(in6); 

recvfrom(sock, buf, buflen, (struct sockaddr *) &in6, &len6); 

既然你在正確長度的函數傳遞,它會工作。

+0

謝謝你的回答。我曾經認爲最後一個參數被提供給'recvfrom',以便函數用實際的發送者地址填充它。我錯了嗎?或者最後一個參數用於這兩個目的:在調用'recvfrom'指示可用的地址緩衝區大小以及調用後存儲實際地址大小之前? – Kolyunya

+1

@Kolyunya它用於兩者。當你調用函數時,你告訴它套接字地址結構有多大,當它返回時,函數已經將它設置爲填充結構的大小。 –

7

將它轉換爲sockaddr*是正確的。

更進一步,人們經常使用sockaddr_storage,因爲它是作爲defined

頭應確定struct sockaddr_storage的結構。 這種結構應是:

  • 大到足以容納所有支持的特定於協議的地址結構
  • 在適當的邊界對準,使得指針可以鑄造成指向特定於協議的地址的結構,並用於 訪問這些結構的領域不對齊的問題

通過這種方式,你可以使用它的一些協議,這樣你就不會boundedn僅IPv6或IPv4。

所以,如果你需要知道什麼kinf的sockaddr的是,你可以檢查存在於每個SOCKADDR結構中的強制性sa_family_t ss_family場,你可以做

struct sockaddr_storage addr; 
socklen_t sa_len = sizeof(addr); 

recvfrom (sock, buffer, sizeof (buffer), (struct sockaddr*) &addr, &sa_len); 

您可能也對這個link或這個one感興趣。

+1

謝謝你參加sockaddr_storage參考,這真的有幫助 – Kolyunya

+0

你有沒有使用'sockaddr_storage'的否定經驗或參考**?我在問,因爲你提到它,而我一直在避免它像魔鬼一樣,因爲唯一的原因是在某些平臺上它是一個純粹禁止大小的結構。 'sockaddr_in6'到目前爲止一直爲我工作,但「一直爲我工作」的真正含義是...... – Damon

+0

據我所知,這是處理多協議案例的好習慣。該標準沒有強制規定所有sockaddr結構體的大小(儘管與線上運行的不同,優化並未被禁止),但唯一需要說明的是sockadrr_storage必須足夠大以容納任何其中。 –