python - 同一个套接字对象如何服务于不同的客户?

标签 python sockets

如文档中所述:Python socket.accept()

Accept a connection. The socket must be bound to an address and listening for connections. The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection.

The newly created socket is non-inheritable.

Changed in version 3.4: The socket is now non-inheritable.

服务器代码是

>>> from socket import *
>>> sock = socket(AF_INET, SOCK_STREAM)
>>> sock.bind(("localhost", 20000))
>>> sock.getsockname()
('127.0.0.1', 20000)
>>> sock.listen(1)
>>> while True: 
...     conn, address = sock.accept()
...     print("Address of client : {0}".format(address))
...     print("Address of socket : {0}".format(conn.getsockname()))
... 
Address of client : ('127.0.0.1', 47165)
Address of socket : ('127.0.0.1', 20000)
Address of client : ('127.0.0.1', 47166)
Address of socket : ('127.0.0.1', 20000)

客户端代码是

>>> from socket import *
>>> sclient1 = socket(AF_INET, SOCK_STREAM)
>>> sclient2 = socket(AF_INET, SOCK_STREAM)
>>> sclient1.connect(("localhost", 20000))
>>> sclient2.connect(("localhost", 20000))

返回的新 socket 对象的地址始终与实际接受连接的原始 socket 相同。

我一直以为服务端会创建一个新的socket对象,不同的随机端口,但是从上面可以看出,即使是多个客户端,新的conn的地址和端口 对象还是一样的。那么服务器如何能够处理多个客户端?


编辑

我知道上面的代码是阻塞的。如果我使用多个线程来处理不同的客户端连接,我将不得不将新的套接字对象和客户端地址发送到我的线程函数。因此,多个线程然后使用相同的服务器地址和端口处理多个客户端。

线程服务器

>>> from socket import *    
>>> import threading
>>> def handler(conn, address):
...     print("Address of client : {0}".format(address))
...     print("Address of socket : {0}".format(conn.getsockname()))
... 
>>> sock = socket(AF_INET, SOCK_STREAM)
>>> sock.bind(("localhost", 20000))
>>> sock.listen(1)
>>> while 1:
...     conn, address = sock.accept()
...     t = threading.Thread(target=handler, args=[conn, address])
...     t.start()
... 
Address of client : ('127.0.0.1', 47169)
Address of socket : ('127.0.0.1', 20000)
Address of client : ('127.0.0.1', 47170)
Address of socket : ('127.0.0.1', 20000)

最佳答案

I always thought that the server would create a new socket object with a different random port

这需要告诉客户端使用哪个端口进行连接。很好,没有必要,请参见下文。这也意味着,您不能有超过 65535 个到单个主机地址的打开连接,这对于某些系统来说可能会中断很多。

How is then the server able to handle multiple clients?

元组 (server_addr, server_port, client_addr, client_port) 在客户端连接后是唯一的。当数据包传入时,网络堆栈会搜索与此元组匹配的打开连接,并将传入数据包重定向到相关套接字(/文件描述符)。

服务器套接字(您在其上执行accept())未连接(它是listen( )ing),但绑定(bind)。这意味着它在另一端没有对等点(没有客户端地址),但它有一个本地地址(服务器端)。

accept() 返回一个新套接字。这个是绑定(bind)连接。 Bound和上面一样:它有一个本地地址和端口。该地址与服务器套接字的地址相同,但是新套接字的状态也是已连接。这意味着我们可以与之通信的另一端有一个已知的对等点(有地址)。我们还有那个点的地址(点地址)和端口(点端口)。此信息足以唯一标识连接。

客户端套接字只接受匹配所有四个(server_addr, server_port, client_addr, client_port)的数据。

关于python - 同一个套接字对象如何服务于不同的客户?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32606250/

相关文章:

java - 将 Android 客户端连接到 NodeJS 中的套接字服务器时出错

python - 显示所有连接到套接字服务器的客户端并向其发送数据

C++ 变量数组

python - Python3.1 中的 View ?

Python:合并2个字典列表

python - flask socket io无法正常工作(Windows 7和10)anaconda和python 3.7

python - 套接字模块,如何发送整数

c# - System.Net.Sockets.SocketException 灾难

python - 将多个参数传递给 python 中重试的 retry_on_exception 参数

python - C++ 中的 Crypto++ :Encrypt in Python , 解密