Python 监听套接字是如何设置的?

Posted

技术标签:

【中文标题】Python 监听套接字是如何设置的?【英文标题】:How does a Python listening socket get setup? 【发布时间】:2019-05-04 02:48:15 【问题描述】:

当您使用 Python 'socket' 模块设置一个简单的 TCP 侦听套接字时,所涉及的不同步骤是什么?

我说的代码是这样的:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('localhost', 50000))
s.listen(1)
conn, addr = s.accept()

s = ... 看起来很简单 - 您表达了创建 ipv4 TCP 套接字的意图,但尚未执行任何操作。

我很好奇的是:

绑定到套接字而不监听是什么意思? 如何使用listen(n) 限制未接受的连接数? 如果你有listen(1),你正在处理你接受的第一个连接,第二个客户端尝试连接,第二个客户端是否在等待SYN-ACK?还是发生了 3 次握手,他正在等待实际数据? 如果第三个客户端尝试连接会发生什么 - 他会立即获得 TCP RST 吗? 在这里设置不接受的连接数是否会在内核中设置一些选项来指示它应该接受多少连接?还是这一切都在 Python 中处理? 你怎么能在不接受的情况下倾听?接受连接是什么意思?

我遇到的每篇文章似乎都假设这些步骤对每个人都有意义,而没有解释每个人的具体作用。他们只是使用通用术语,例如

listen() 开始监听连接

bind() 绑定到套接字

accept() 只接受连接

通过在定义中使用该词来定义一个词是一种解释某事的愚蠢方式。

【问题讨论】:

相关 - Why bind a socket to an address? 【参考方案1】:

它基本上是来自 POSIX c 调用的一对一,因此我包含了指向手册页的链接,以便您可以阅读它们的解释和相应的 c 代码:

socket 通过您指定的地址系列的命名空间中的文件描述符创建一个通信端点,但既不分配地址也不分配端口。

bind 为所述套接字分配一个地址和端口,如果您请求一个您没有权限的端口,则可以随机选择一个端口。 (如

listen 使特定的套接字以及地址和端口成为被动的,这意味着它将通过接受调用接受传入连接。要一个接一个地处理多个连接,您需要指定一个包含它们的积压工作,在您处理一个连接时到达的连接会被附加。一旦 backlog 满了,系统就会对这些系统做出相应的响应,方法是通过扣留 SYN、扣留 ACK 响应等方式使它们重新连接。

像往常一样,您可以找到更好的人explaining the previous。

accept 然后创建一个新的非侦听套接字,该套接字与一个新的文件描述符相关联,然后您可以将其用于与所述连接方进行通信。 accept 还可以作为执行流程的导向器,有效地阻止进一步的进展,直到队列中实际有一个连接可供它使用,例如自旋锁。解决这个问题的唯一方法是声明套接字是非阻塞的,在这种情况下它会立即返回错误。

【讨论】:

小更正:bind在你请求一个你没有权限的端口时不会随机选择一个端口。绑定将简单地以EPERM 失败,从而使套接字未绑定。如果您尝试以需要建立地址的方式使用套接字(即使对于listen)并且您之前没有成功绑定它,那么系统会为你选择一个“随机”的端口。

以上是关于Python 监听套接字是如何设置的?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Win7设置QTcpServer单独监听端口

linux内核如何区分连接套接字和监听套接字?

Python网络编程_TCP(简略版)

python中的socket

QT 网络编程问题

Python 2 进程在套接字上通信