為什么服務(wù)端程序都需要先 listen 一下?
時(shí)間:2021-10-11 14:21:40
手機(jī)看文章
掃描二維碼
隨時(shí)隨地手機(jī)看文章
[導(dǎo)讀]大家都知道,在創(chuàng)建一個(gè)服務(wù)器程序的時(shí)候,需要先listen一下,然后才能接收客戶端的請求。例如下面的這段代碼我們再熟悉不過了。int?main(int?argc,?char?const?*argv[]){?int?fd?=?socket(AF_INET,?SOCK_STREAM,...
大家都知道,在創(chuàng)建一個(gè)服務(wù)器程序的時(shí)候,需要先 listen 一下,然后才能接收客戶端的請求。例如下面的這段代碼我們再熟悉不過了。
int?main(int?argc,?char?const?*argv[])
{
?int?fd?=?socket(AF_INET,?SOCK_STREAM,?0);
?bind(fd,?...);
?listen(fd,?128);
?accept(fd,?...);
那么我們今天來思考一個(gè)問題,為什么需要 listen 一下才能接收連接?或者換句話說,listen 內(nèi)部執(zhí)行的時(shí)候到底干了啥?如果你也想搞清楚 listen 內(nèi)部的這些秘密,那么請跟我來!一、創(chuàng)建 socket
服務(wù)器要做的第一件事就是先創(chuàng)建一個(gè) socket。具體就是通過調(diào)用 socket 函數(shù)。當(dāng) socket 函數(shù)執(zhí)行完畢后,在用戶層視角我們是看到返回了一個(gè)文件描述符 fd。但在內(nèi)核中其實(shí)是一套內(nèi)核對象組合,大體結(jié)構(gòu)如下。這里簡單了解這個(gè)結(jié)構(gòu)就行,后面我們在源碼中看到函數(shù)指針調(diào)用的時(shí)候需要回頭再來看它。二、內(nèi)核執(zhí)行 listen
2.1 listen 系統(tǒng)調(diào)用
我在 net/socket.c 下找到了 listen 系統(tǒng)調(diào)用的源碼。//file:?net/socket.c
SYSCALL_DEFINE2(listen,?int,?fd,?int,?backlog)
{
?//根據(jù)?fd?查找?socket?內(nèi)核對象
?sock?=?sockfd_lookup_light(fd,?