sockaddr和sockaddr_in詳解


struct sockaddr 和 struct sockaddr_in 這兩個結構體用來處理網絡通信的地址。

一、sockaddr

sockaddr在頭文件#include <sys/socket.h>中定義,sockaddr的缺陷是:sa_data把目標地址和端口信息混在一起了,如下:

struct sockaddr {   unsigned short sa_family;//2字節,地址族,AF_xxx
  char sa_data[14]; //14字節,包含套接字中的目標地址和端口信息 
};

二、sockaddr_in

sockaddr_in在頭文件#include<netinet/in.h>或#include <arpa/inet.h>中定義,該結構體解決了sockaddr的缺陷,把port和addr 分開儲存在兩個變量中,如下: 

 

struct sockaddr_in { short            sin_family;    // 2 字節 ,地址族,e.g. AF_INET, AF_INET6
     unsigned short   sin_port;      // 2 字節 ,16位TCP/UDP 端口號 e.g. htons(3490),
     struct in_addr   sin_addr;      // 4 字節 ,32位IP地址
     char             sin_zero[8];   // 8 字節 ,不使用
};
struct in_addr { unsigned long s_addr;          // 32位IPV4地址打印的時候可以調用inet_ntoa()函數將其轉換為char *類型.
};

sin_port和sin_addr都必須是網絡字節序(NBO),一般可視化的數字都是主機字節序(HBO)

三、總結

二者長度一樣,都是16個字節,即占用的內存大小是一致的,因此可以互相轉化。二者是並列結構,指向sockaddr_in結構的指針也可以指向sockaddr。

sockaddr常用於bind、connect、recvfrom、sendto等函數的參數,指明地址信息,是一種通用的套接字地址。 
sockaddr_in 是internet環境下套接字的地址形式。所以在網絡編程中我們會對sockaddr_in結構體進行操作,使用sockaddr_in來建立所需的信息,最后使用類型轉化就可以了。一般先把sockaddr_in變量賦值后,強制類型轉換后傳入用sockaddr做參數的函數:sockaddr_in用於socket定義和賦值;sockaddr用於函數參數。

 

注釋中標明了屬性的含義及其字節大小,這兩個結構體一樣大,都是16個字節,而且都有family屬性,不同的是:

sockaddr用其余14個字節來表示sa_data,而sockaddr_in把14個字節拆分成sin_port, sin_addr和sin_zero分別表示端口、ip地址。sin_zero用來填充字節使sockaddr_in和sockaddr保持一樣大小。

 

sockaddr和sockaddr_in包含的數據都是一樣的,但他們在使用上有區別:

程序員不應操作sockaddr,sockaddr是給操作系統用的

程序員應使用sockaddr_in來表示地址,sockaddr_in區分了地址和端口,使用更方便。

 

一般的用法為:

程序員把類型、ip地址、端口填充sockaddr_in結構體,然后強制轉換成sockaddr,作為參數傳遞給系統調用函數

 

四、使用

//創建sockaddr_in結構體變量
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));  //每個字節都用0填充
serv_addr.sin_family = AF_INET;  //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具體的IP地址
serv_addr.sin_port = htons(1234);  //端口號

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM