全连接队列与半连接队列
在服务器中,监听套接字维护两个队列:
- 半连接队列(SYN Queue):存放那些已经收到客户端SYN包,但还未完成三次握手的连接。
- 全连接队列(Accept Queue):存放那些已经完成三次握手的连接,等待应用程序调用
accept
函数来处理。
select
/poll
/epoll
的作用
- 这些系统调用监视监听套接字的状态,以检测是否有新的连接请求到达。
- 当监听套接字上有新的连接请求并且该连接已经完成三次握手,被放入全连接队列时,监听套接字会变为可读状态。
select
、poll
或epoll
会返回,通知应用程序监听套接字上有可读事件。
具体流程
-
服务器初始化:
- 服务器创建监听套接字,并调用
bind
、listen
等函数进行初始化。 - 服务器调用
select
、poll
或epoll
来监视监听套接字。
- 服务器创建监听套接字,并调用
-
客户端发起连接:
- 客户端向服务器发起连接请求,发送SYN包。
- 服务器的TCP/IP协议栈收到SYN包,将连接放入半连接队列,并回复SYN-ACK包。
-
三次握手完成:
- 客户端收到SYN-ACK包后,回复ACK包。
- 服务器的TCP/IP协议栈收到ACK包后,将连接从半连接队列移到全连接队列,表示三次握手完成。
-
监听套接字变为可读:
- 当监听套接字的全连接队列中有新的连接时,监听套接字变为可读状态。
select
、poll
或epoll
返回,通知应用程序监听套接字上有新的可读事件。
-
调用
accept
:- 服务器调用
accept
函数,从全连接队列中取出一个已经完成三次握手的连接,返回一个新的套接字描述符,用于与客户端进行通信。
- 服务器调用
结论
select
、poll
和 epoll
监视监听套接字的状态,以检测全连接队列中是否有新的连接。当全连接队列中有新的连接时,监听套接字会变为可读状态,这些系统调用会返回,通知应用程序可以调用accept
函数来处理新的连接。