sockaddr在頭文件#include <sys/socket.h>
中定義,sockaddr的缺陷是:sa_data把目標地址和端口信息混在一塊兒了,以下:程序員
struct sockaddr { unsigned short sa_family;//2字節,地址族,AF_xxx
char sa_data[14]; //14字節,包含套接字中的目標地址和端口信息
};
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。socket
sockaddr經常使用於bind、connect、recvfrom、sendto等函數的參數,指明地址信息,是一種通用的套接字地址。
sockaddr_in 是internet環境下套接字的地址形式。因此在網絡編程中咱們會對sockaddr_in結構體進行操做,使用sockaddr_in來創建所需的信息,最後使用類型轉化就能夠了。通常先把sockaddr_in變量賦值後,強制類型轉換後傳入用sockaddr作參數的函數:sockaddr_in用於socket定義和賦值;sockaddr用於函數參數。函數
註釋中標明瞭屬性的含義及其字節大小,這兩個結構體同樣大,都是16個字節,並且都有family屬性,不一樣的是:spa
sockaddr用其他14個字節來表示sa_data,而sockaddr_in把14個字節拆分紅sin_port, sin_addr和sin_zero分別表示端口、ip地址。sin_zero用來填充字節使sockaddr_in和sockaddr保持同樣大小。操作系統
sockaddr和sockaddr_in包含的數據都是同樣的,但他們在使用上有區別:指針
程序員不該操做sockaddr,sockaddr是給操做系統用的code
程序員應使用sockaddr_in來表示地址,sockaddr_in區分了地址和端口,使用更方便。blog