为何Python调用listen后会生成ESTABLISHED状态的Socket?
为什么调用listen但未accept时,netstat会显示ESTABLISHED状态的Socket?
首先纠正一个常见误解:accept并不是创建ESTABLISHED状态Socket的触发点,内核在TCP三次握手完成后就会自动创建这个Socket。
核心原因拆解:
TCP三次握手与内核队列机制
服务器调用listen()后,内核会为监听Socket维护两个关键队列:- 半连接队列(SYN队列):存储仅完成SYN包交换、未完成三次握手的连接请求
- 全连接队列(accept队列):存储已经完成三次握手的连接
当客户端发送SYN包,服务器回复SYN+ACK,客户端再返回ACK包后,三次握手流程完成。此时内核会立即创建一个新的Socket(状态标记为ESTABLISHED),并将其放入全连接队列,等待用户进程调用accept()来获取该Socket的文件描述符,进而开展数据交互。
netstat显示的ESTABLISHED Socket的本质
你通过netstat看到的ESTABLISHED状态Socket,并非原本处于LISTEN状态的监听Socket,而是内核在三次握手完成后自动生成的新Socket。这个Socket已经处于连接完成状态,只是用户进程尚未通过accept()将其从队列中取出使用。关于源码查找的提示
你未找到该Socket的创建逻辑,是因为这个操作发生在内核态的TCP协议栈握手处理流程中,而非listen()或accept()的用户态代码里。以Linux内核为例,处理三次握手最后一个ACK包的函数(如tcp_v4_do_rcv)会完成连接建立,并调用inet_csk_complete_hashdance等内核函数创建并初始化新Socket,随后将其加入全连接队列。
内容的提问来源于stack exchange,提问作者Jiwon
相关产品推荐
相关产品推荐

