Winsock2服务端未调用accept函数时客户端仍可连接成功问题咨询
问题原因说明
- 该现象是TCP协议和Winsock内核实现的正常逻辑,不属于代码Bug。TCP连接的三次握手由操作系统内核直接处理,和应用层是否调用
accept无直接关联:
当服务端调用listen函数成功后,操作系统内核会为该监听套接字维护两个独立队列:- 半连接队列(SYN队列):存储已收到客户端SYN请求、已回复SYN+ACK,尚未收到客户端第三次握手ACK包的连接
- 全连接队列(ACCEPT队列):存储已经完成三次握手全过程,等待应用层调用
accept函数取出的连接
- 客户端
connect函数返回成功的触发时机是客户端侧收到服务端返回的SYN+ACK包、完成自身侧的握手流程,此时不需要等待服务端应用层执行任何操作,自然就会返回有效的套接字描述符。 - 你当前的测试逻辑中,服务端已经执行了
listen,内核会自动处理所有进来的连接请求,只要全连接队列尚未被占满,三次握手就会正常完成,客户端就能拿到有效连接。当连接数超过listen第二个参数指定的队列长度上限后,新的连接请求会被内核直接丢弃,此时客户端connect才会返回报错。
补充验证方式:你可以同时启动数十个客户端尝试连接该服务端,达到队列上限后后续的客户端连接就会失败;抓包也能看到之前成功的连接三次握手流程是完整的,只是服务端应用层没有将连接从内核队列取出而已。
内容的提问来源于stack exchange,提问作者malidu
相关产品推荐
相关产品推荐

