我的意思是,當我檢查兩個struct sockaddr
是否具有相同的IP地址和端口號時,我應該比較哪些字段是struct sockaddr
?那麼sockaddr_in
呢?如何比較C中的套接字地址?
我可以只投至sockaddr
,並將其與真實sockaddr
比較?
我的意思是,當我檢查兩個struct sockaddr
是否具有相同的IP地址和端口號時,我應該比較哪些字段是struct sockaddr
?那麼sockaddr_in
呢?如何比較C中的套接字地址?
我可以只投至sockaddr
,並將其與真實sockaddr
比較?
首先您需要檢查系列(IPv4,IPv6或其他)。然後,您可以將每個sockaddr轉換爲適當的「派生」類型,如sockaddr_in。看到蘋果如何做在這裏:http://www.opensource.apple.com/source/postfix/postfix-197/postfix/src/util/sock_addr.c
首先,當你正在處理值,你需要使用struct sockaddr_storage
,因爲struct sockaddr
僅供指針安全的,否則你會碰到大小和校準問題。
其次,struct sockaddr
是通過C爲「基類」。第一個成員是sa_family_t sa_family;
(儘管這個struct
早於結構成員在單獨的命名空間中,每個「子類」使用一個唯一的前綴(我遇到過至少40個子類))。
第三 - 雖然你可能會認爲每個struct
,事實證明,類的大小因內核/庫版本而異。所以,你總是必須通過sizeof()
實際struct sockaddr_FOO
爲了。例如,舊版本的struct sockaddr_in6
沒有sin6_scope_id
成員。
你或許應該把這個包在一個struct
的理智(並提供各種輔助功能):
struct SocketAddress
{
struct sockaddr_storage addr;
socklen_t addr_len;
};
然後,你的比較的代碼看起來像:
// returns < 0 if (left < right)
// returns > 0 if (left > right)
// returns 0 if (left == right)
// Note that in general, "less" and "greater" are not particularly
// meaningful, but this does provide a strict weak ordering since
// you probably need one.
int socket_cmp(struct SocketAddress *left, struct SocketAddress *right)
{
socklen_t min_addr_len = MIN(left->addr_len, right->addr_len;
// If head matches, longer is greater.
int default_rv = right->addr_len - left->addr_len;
int rv = memcmp(left, right, min_addr_len);
return rv ?: default_rv;
}
別急!雖然上面的代碼是足夠的,如果你小心,謹慎仍然需要大量的細節。例如:
所有的套接字地址都會在程序的單次運行中產生,還是會從某些外部介質讀取一些地址?對於後一種情況,您將需要對sin6_scope_id
等案例進行規範化處理。
您是否必須在同一個程序中處理IPv4和IPv6上的IPv4地址(映射類似ffff::1.2.3.4
)?最簡單的方法是在您的程序中專門處理IPv6,因爲相關功能也接受IPv4地址。爲了獲得最佳的便攜性,請務必禁用(使用setsockopt
)IPV6_V6ONLY
標誌。或者,您可以啓用該標誌來幫助確保IPv6地址永遠不會包含IPv4地址。 (請注意,查詢localhost
不同 - 但這是所有域查找的一般問題,這可能會返回多個結果)。
你知道'sock_addr.h'是否已經包含在Mac/iOS上嗎? – johk95 2014-01-05 12:49:58
@ johk95你可以在url中看到,sock_addr.h和sock_addr.c的源代碼實際上來自於postfix項目。 – kevin 2014-09-26 03:27:16
[是的,我們知道蘋果是如何做到的。](https://www.imperialviolet.org/2014/02/22/applebug.html)^^ – Downvoter 2015-12-12 18:36:46