listen函數僅由服務器端調用,主要乾了兩個事情:
- 將套接字從closed轉態轉爲listen狀態;
- 函數的第二個參數backlog指定了內核爲相應套接字排隊的最大連接個數。
#include <sys/socket.h>
int listen(int sockfd, int backlog);
對於每個給定的監聽套接字,內核都會維護兩個隊列:未完成連接隊列(incomplete connection queue)和已完成連接隊列(completed connection queue)。而listen函數的第二個參數backlog就規定了這兩個隊列的大小。
在tcp三次握手中,當客戶端第一次發送連接到服務端時,客戶端套接字由closed轉爲syn_sent,當服務端收到後,這個連接就進入未完成連接隊列,此時服務端套接字狀態有listen轉爲syn_rcvd;當第三次握手客戶端向服務端返回服務端syn的ack時,客戶端套接字狀態由syn_sent轉爲established,服務端收到第三次握手後,連接信息就從未完成連接隊列中轉移到已完成連接隊列,套接字狀態也從syn_rcvd轉爲established。
之後就是調用accept函數從已完成連接隊列中獲取連接,若該隊列爲空,則accept函數陷入阻塞狀態,直到有新的連接過來爲止。