從Linux原始碼看Socket(TCP)的bind
阿新 • • 發佈:2020-10-16
# 從Linux原始碼看Socket(TCP)的bind
## 前言
筆者一直覺得如果能知道從應用到框架再到作業系統的每一處程式碼,是一件Exciting的事情。 今天筆者就來從Linux原始碼的角度看下Server端的Socket在進行bind的時候到底做了哪些事情(基於Linux 3.10核心)。
## 一個最簡單的Server端例子
眾所周知,一個Server端Socket的建立,需要socket、bind、listen、accept四個步驟。
![](https://oscimg.oschina.net/oscnet/up-22ef7810d0c94cc4deda470e55ba02c91b5.png)
程式碼如下:
```
void start_server(){
// server fd
int sockfd_server;
// accept fd
int sockfd;
int call_err;
struct sockaddr_in sock_addr;
sockfd_server = socket(AF_INET,SOCK_STREAM,0);
memset(&sock_addr,0,sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
sock_addr.sin_port = htons(SERVER_PORT);
// 這邊就是我們今天的聚焦點bind
call_err=bind(sockfd_server,(struct sockaddr*)(&sock_addr),sizeof(sock_addr));
if(call_err == -1){
fprintf(stdout,"bind error!\n");
exit(1);
}
// listen
call_err=listen(sockfd_server,MAX_BACK_LOG);
if(call_err == -1){
fprintf(stdout,"listen error!\n");
exit(1);
}
}
```
首先我們通過socket系統呼叫建立了一個socket,其中指定了SOCK_STREAM,而且最後一個引數為0,也就是建立了一個通常所有的TCP Socket。在這裡,我們直接給出TCP Socket所對應的ops也就是操作函式。
![](https://oscimg.oschina.net/oscnet/up-ffb587cdd5c37946484f4b78df5053abdef.png)
如果你想知道上圖中的結構是怎麼來的,可以看下筆者以前的部落格:
```
https://my.oschina.net/alchemystar/blog/1791017
```
## bind系統呼叫
bind將一個本地協議地址(protocol:ip:port)賦予一個套接字。例如32位的ipv4地址或128位的ipv6地址+16位的TCP活UDP埠號。
```
#include