從Linux原始碼看Socket(TCP)的listen及連線佇列
阿新 • • 發佈:2020-10-20
# 從Linux原始碼看Socket(TCP)的listen及連線佇列
## 前言
筆者一直覺得如果能知道從應用到框架再到作業系統的每一處程式碼,是一件Exciting的事情。 今天筆者就來從Linux原始碼的角度看下Server端的Socket在進行listen的時候到底做了哪些事情(基於Linux 3.10核心),當然由於listen的backlog引數和半連線hash表以及全連線佇列都相關,在這一篇部落格裡也一塊講了。
## Server端Socket需要Listen
眾所周知,一個Server端Socket的建立,需要socket、bind、listen、accept四個步驟。
今天筆者就聚焦於Listen這個步驟。
![](https://oscimg.oschina.net/oscnet/up-231a760e7ed2dcc880b80930f3e8ca8a32e.png)
程式碼如下:
```
void start_server(){
// server fd
int sockfd_server;
// accept fd
int sockfd;
int call_err;
struct sockaddr_in sock_addr;
......
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也就是操作函式。
![codegen](https://oscimg.oschina.net/oscnet/up-ffb587cdd5c37946484f4b78df5053abdef.png)
如果你想知道上圖中的結構是怎麼來的,可以看下筆者以前的部落格:
```
https://my.oschina.net/alchemystar/blog/1791017
```
## Listen系統呼叫
好了,現在我們直接進入Listen系統呼叫吧。
```
#include