bind()與connect()——計網中socket的使用


搬自c語言中文網:http://c.biancheng.net/cpp/html/3033.html

Socket()函數用來創建套接字,服務器要用bind()函數將套接字與特定的IP地址和端口綁定起來,這樣流經該IP地址和端口的數據才能交給套接字處理:客戶端用connect()建立連接。

bind() 函數

1 int bind(int sock, struct sockaddr *addr, socklen_t addrlen); //Linux
2 int bind(SOCKET sock, const struct sockaddr *addr, int addrlen); //Windows 

sock 為 socket 文件描述符,addr 為 sockaddr 結構體變量的指針,addrlen 為 addr 變量的大小,可由 sizeof() 計算得出

 1 //創建套接字
 2 int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 3 
 4 //創建sockaddr_in結構體變量
 5 struct sockaddr_in serv_addr;
 6 memset(&serv_addr, 0, sizeof(serv_addr));  //每個字節都用0填充
 7 serv_addr.sin_family = AF_INET;  //使用IPv4地址
 8 serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具體的IP地址
 9 serv_addr.sin_port = htons(1234);  //端口
10 
11 //將套接字和IP、端口綁定
12 bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

sockaddr_in 結構體

struct sockaddr_in{
    sa_family_t     sin_family;   //地址族(Address Family),也就是地址類型
    uint16_t        sin_port;     //16位的端口號
    struct in_addr  sin_addr;     //32位IP地址
    char            sin_zero[8];  //不使用,一般用0填充
};

  

in_addr 結構體

struct in_addr{
    in_addr_t  s_addr;  //32位的IP地址
};

in_addr_t 在頭文件 <netinet/in.h> 中定義,等價於 unsigned long,長度為4個字節。也就是說,s_addr 是一個整數,而IP地址是一個字符串,所以需要 inet_addr() 函數進行轉換,例如:

unsigned long ip = inet_addr("127.0.0.1");
printf("%ld\n", ip);

 

為什么使用 sockaddr_in 而不使用 sockaddr

struct sockaddr{
    sa_family_t  sin_family;   //地址族(Address Family),也就是地址類型
    char         sa_data[14];  //IP地址和端口號
};

sockaddr 和 sockaddr_in 的長度相同,都是16字節,只是將IP地址和端口號合並到一起,用一個成員 sa_data 表示。要想給 sa_data 賦值,必須同時指明IP地址和端口號,例如”127.0.0.1:80“,遺憾的是,沒有相關函數將這個字符串轉換成需要的形式,也就很難給 sockaddr 類型的變量賦值,所以使用 sockaddr_in 來代替。這兩個結構體的長度相同,強制轉換類型時不會丟失字節,也沒有多余的字節。

可以認為,sockaddr 是一種通用的結構體,可以用來保存多種類型的IP地址和端口號,而 sockaddr_in 是專門用來保存 IPv4 地址的結構體。

 


免責聲明!

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



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