1. 程式人生 > >四、初識Socket套接字結構體

四、初識Socket套接字結構體

協議 綁定 mpp pre glib main 密鑰 解決 有時

一、初識Socket套接字結構體


1、通用套接字結構體類型

   struct sockaddr
    {
        sa_family_t sa_family; //協議簇
        char sa_data[14]; //協議簇數據
    }

通用套接字結構體可以在不同的協議簇之間進行強制轉化,Socket網絡編程中幾乎所有套接字API函數的形參都是通用套接字結構體struct sockaddr。

存在問題:

  • 通用套接字結構體對編程的角度來說,設置很不方便,我們以以太網協議來說,當要設置端口號、IP地址等,那麽我需要將端口號與IP地址進行數據組合綁定,然後賦值給該結構,是不能獨立賦值。

  • 為解決上述問題,以太網協議中經常用到的是下述結構體,這樣就可以給人以直觀的方式去填充套接字結構體。

2、以太網套接字結構體

struct sockaddr_in
    {
        u8 sin_len;
        u8 sin_family;
        u16 sin_port;
        struct in_addr sin_addr;
        char sin_zero[8]; 
    }
  • 結構體成員列表
結構體成員 參數含義 備註
u8 sin_len 結構體sockaddr_in的長度 一般大小為固定16字節
u8 sin_family 協議族類型 見下表
u16 sin_port 16位端口號 XXX
struct in_addr sin_addr 32位IP地址 INADDR_ANY //表示可以與任何主機通信
char sin_zero[8] //未使用 填充位,一般都設置為0

  • 協議簇列表

協議簇類型(sin_family) 參數含義
AF_INET 以太網/IPv4協議
AF_INET6 以太網/IPv6協議
AF_LOCAL Unix域協議
AF_ROUTE 路由套接口
AF_KEY 密鑰套接口

Note : 我們主要使用的是以太網,所以sin_family成員一般都為AF_INET

,有時候我們看到協議簇類型是PF_* 而不是 AF*,這是因為glibc的實現機制是posix,其實都是同一個東西。


存在問題:

  • Socket網絡編程中幾乎所有套接字API函數的形參都是通用套接字結構體struct sockaddr,而我們初始化傳遞的參數是以太網套接字結構體struct sockaddr類型,這樣是否就存在類型不一致的問題?
Exzampp:
  // API函數: fun(struct sockaddr)
 //  用戶實際調用: 
 int main()
 {
     struct sockaddr_in;
     fun(sockaddr_in);    //是否存在問題?
 }
     

問題解答:

  • 上述操作完全可以,因為這兩個結構體在內存上的大小完全一致都是16個字節,所以隱式的轉換不存在其它問題。
  • struct sockaddr = struct sockaddr_in 。 (不存在問題)

技術分享圖片

  *圖示:兩種結構類型的內存存儲*

四、初識Socket套接字結構體