套接字地址結構
阿新 • • 發佈:2019-03-03
無需 p地址 廠商 color 我們 套接字地址結構 str 程序 參數
每個協議族都定義了它自己的套接字地址結構。這些結構的名字均以sockaddr_開頭,並以對應每個協議地址族的唯一後綴結尾。
IPV4套接字地址結構
IPv4地址和TCP或UDP端口號在套接字地址結構中總是以網絡字節序來存儲。
struct in_addr { //in_addr_t數據類型是一個至少32位的無符號整數類型 in_addr_t s_addr; /*32位IPv4地址,網絡字節序*/ } struct sockaddr_in { uint8_t sin_len; /*無符號8位整數*/ //sa_family_t可以是任何無符號整數類型,在支持長度字段的實現中,//sa_family_t通常是一個8位的無符號整數, //在不支持長度的字段實現中,則是一個長度為16位的無符號整數。 sa_family_t sin_family; /*套接字地址結構的地址族*/ //in_port_t必須是一個至少16位的無符號整數類型 in_port_t sin_port; /*TCP或UDP端口,一般為uint16_t*/ struct in_addr sin_addr; char sin_zero[8];/*未使用*/ }
- sin_len字段表示結構體的長度,並不是所有的廠家都支持這個字段,而且POSIX規範也不要求有這個成員,所以即使有了長度字段,在Socket編程中也無需檢測和設置這個字段,除非涉及路由套接字(由處理來自不同協議族的套接字地址結構的例程(如路由表處理代碼)在內核中使用)
- POSIX規範只需要s_addr,sin_family和sin_port這三個字段,但是幾乎所有實現都增加了sin_zero字段,所以套接字地址結構大小都是至少16個字節。
-
32位的IPv4地址存在兩種不同的訪問方法。例如,若serv定義位某個網絡套接字地址結構,那麽serv.sin_addr將按in_addr結構引用其中的32位IPv4地址,而serv.sin_addr.s_addr將按in_addr_t(通常是一個無符號32位整數)來引用同一個32位IP地址。因此我們必須正確地使用IPv4地址,尤其是在將它作為函數的參數時,因為編譯器對傳遞結構和傳遞整數的處理是完全不同的。
通用套接字地址結構
當作為一個參數傳遞進任何套接字函數時,套接字地址總是以引用形式來傳遞,以這樣指針作為參數的任何套接字函數必須處理來自所有支持的任何協議族的套接字地址結構,而各個廠商所定義的套接字結構又有區別,所以就定義了一個通用套接字地址結構struct sockaddr,這個結構定義在頭文件<sys/socket.h>中:
struct sockaddr { uint8_t sa_len; sa_family_t sa_family; char sa_data[14]; }
- sa_len是結構體長度字段
- sa_family表示地址協議族
- 有14個元素的字符數組sa_data。
在有結構體長度的地址結構中,sa_family通常是一個8位無符號整數,那麽結構體struct sockaddr的長度至少為16個字節。在套接字函數中,通常地址參數是一個指向struct sockaddr類型的指針
從網絡應用程序開發的角度來看,通用的套接字地址結構的唯一用途就是對指向特定與協議的套接字地址結構的指針執行強制類型轉換,但是在操作系統的內核中,內核必須使用struct sockaddr *類型來檢查sa_family字段的值,從而確定這個結構的真實類型。
IPv6套接字的地址結構
struct in6_addr { uint8_t s6_addr[16];/*Ipv6的128位地址*/ } #define SIN6_LEN struct sockaddr_in6 { uint8_t sin6_len;/*結構體長度*/ sa_family_t sin6_family;/*協議族*/ in_port_t sin6_port;/*端口,網絡字節序*/ uint32_t siin6_flowinfo;/*分成兩個字段,低序20位是流標,高序12位保留*/ struct in6_addr sin6_addr;/*IPv6的128位地址,網絡字節序*/ uint32_t sin6_scope_id; /*標識具備範圍的地址,最常見的是鏈路局部地址的結構索引*/ }
套接字地址結構