1. 程式人生 > >網絡編程中重要的幾個數據結構和函數

網絡編程中重要的幾個數據結構和函數

def 選擇 結構體 重要 參數 結構 編程 存在 實現

IPv4相關結構:

struct in_addr
{
    in_addr_t          s_addr;  //表示32位的IP地址,32位無符號整型
}

struct sockaddr_in
{
    uint8_t            sin_len;       //表示該結構體的長度,8位無符號整型
    sa_family_t        sin_family;    //表示套接口使用的協議族,8位無符號整型
    in_port_t          sin_port;      //表示套接口使用的端口號,16位無符號整型
    struct in_addr     sin_addr;      //表示IP地址,32位無符號整型
    char               sin_zero[8];   //該成員基本不使用,總是置為0
}
  • sin_len成員是不要求一定存在的,即便這個成員存在,也無需設置它或者檢查它。換句話說就是一般情況下,我們用不到這個成員。

  • sin_family,sin_addr,sin_port這三個成員是必須的。並且幾乎所有的實現都增加了sin_zero成員。

  • sin_family的類型與sin_len成員有關,如果結構體中定義了成員sin_len,那麽sin_family一般就是8位無符號整型。

  • 如果結構體中沒有定義成員sin_len,那麽sin_family一般就是16位無符號整型,這樣一來整個結構體的大小至少是16字節(1+1+2+4+8)。

IPv6相關結構:

struct in6_addr
{
    unit8_t              s6_addr[16]; //表示128位的IP地址,這裏采用數組的形式  
}

struct sockaddr_in6
{
    uint8_t              sin6_len;         //表示該結構體的長度,8位無符號整型
    sa_family_t          sin6_family;      //表示套接口使用的協議族,8位無符號整型
    in_port_t            sin_port;         //表示套接口使用的端口號,16位無符號整型
    uint32_t             sin_flowinfo;     //低序20位是流標簽,高序12位保留
    struct in6_addr      sin6_addr         //表示128位的IP地址
    uint32_t             sin6_scope_id;    //標識對於具備範圍的地址而言有意義的範圍
}
  • 28個字節

通用套接口地址結構:

struct sockaddr
{
    uint8_t              sa_len;
    sa_family_t          sa_family;
    char                 sa_data[14];        //表示14字節的協議地址

}
  • 當作為參數傳遞給任一個套接口函數時,套接口地址結構總是通過指針來傳遞,但通過指針來取得此參數的套接口函數必須處理來自所支持的任何協議族的套接口地址結構。因此通過定義sockaddr來獲取不同的套接口地址結構。
  • 大小16個字節

新的通用套接口地址結構:

struct sockaddr_storage
{
    uint8_t              ss_len;             //表示該結構的長度
    sa_family_t          ss_family;          //表示協議族
    char __ss_padding[_SS_PADSIZE];          
}
  • 原有的通用數據結構sockaddr只有16個字節,無法兼容ipv6格式,sockaddr_storage足夠大,可以容納任何套接字接口地址
  • sockaddr_storage 能滿足最苛刻的對齊要求
  • 想使用sockaddr_storage中,除了ss_len和ss_family外的其他字段,必須強制轉換成其他類型(如sockaddr),再獲取。

inet_pton和inet_ntop函數

這兩個是隨ipv6一起出現的新函數,支持ipv4和ipv6,函數名稱中p的意思是表達(presentation),n的意思是數值(numeric),表達是ACSII字符串,數值是內存裏的二進制值,顧名思義,inet_pton,將字符串轉為數值,inet_ntop,將數值轉為字符串。

#include <arpa/inet.h>
int inet_pton(int family, const char *strptr, void *addrstr); //成功返回1,strptr格式錯誤返回0,失敗返回-1
const char *inet_ntop(int family, const void *addrstr, char *strptr, size_t len); //成功則返回指向結果的指針,失敗返回NULL
  • family參數根據協議族的不同,選擇AF_INET或AF_INET6
  • inet_pton 將strptr指向的字符串,轉為數值,存放在addstr指向的內存中
  • inet_ntop 做相反的運算,len參數是strptr單元的大小,防止溢出。為有助於指定大小,C語言中有做如下定義。
#incldue <arpa/inet.h>
#define INET_ADDRSTRLEN    16
#define INET6_ADDRSTRLEN   46

網絡編程中重要的幾個數據結構和函數