Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 同一个套接字对象如何服务于不同的客户端?_Python_Sockets - Fatal编程技术网

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

Python 同一个套接字对象如何服务于不同的客户端?,python,sockets,Python,Sockets,如文件中所述: 接受连接。套接字必须绑定到一个地址,并且 监听连接。返回值是一对(conn,address) 其中conn是一个新的套接字对象,可用于在其上发送和接收数据 连接和地址是绑定到服务器上套接字的地址 连接的另一端 新创建的套接字不可继承 在版本3.4中更改:套接字现在不可继承 服务器代码是 >>> from socket import * >>> sock = socket(AF_INET, SOCK_STREAM) >>> so

如文件中所述:

接受连接。套接字必须绑定到一个地址,并且 监听连接。返回值是一对(conn,address) 其中conn是一个新的套接字对象,可用于在其上发送和接收数据 连接和地址是绑定到服务器上套接字的地址 连接的另一端

新创建的套接字不可继承

在版本3.4中更改:套接字现在不可继承

服务器代码是

>>> 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
对象,但是如上所述,即使对于多个客户端,新的
conn
对象的地址和端口仍然是相同的。那么服务器如何处理多个客户端呢


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

线程服务器

我一直认为服务器会创建一个具有不同随机端口的新套接字对象

这需要告诉客户机要使用哪个新端口进行连接。很好,这是没有必要的,见下文。这也意味着,到单个主机地址的开放连接不能超过65535个,这可能会对某些系统造成相当大的破坏

那么服务器如何处理多个客户端呢

客户端连接后,元组
(服务器地址、服务器端口、客户端地址、客户端端口)
是唯一的。当数据包进入时,网络堆栈将搜索与此元组匹配的打开连接,并将传入的数据包重定向到相关套接字(/文件描述符)

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

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


客户端套接字只接受与所有四个
(服务器地址、服务器端口、客户端地址、客户端端口)匹配的数据,每个客户端连接都有一个随机的服务器端口来标识连接?你把套接字和端口搞混了。只需要一个服务器端端口,但服务器需要每个连接一个套接字。还有一个疑问。服务器如何能够在同一套接字上侦听和服务客户机?每当有请求出现时,操作系统是否总是选择一个未连接但绑定的套接字,这与已连接和绑定的套接字不同?@kartikana请注意术语。套接字本质上是操作系统为您提供的与网络堆栈交互的句柄。您的套接字不能同时处于侦听和连接状态。但是,如果连接建立请求(例如TCP
SYN
)数据包与已建立的连接相匹配,则该数据包将由现有连接处理(因此通常会被静默忽略)。如果您已经有一个地址,您就无法创建具有四倍相同地址的连接。谢谢您提供的信息。你能给我指一个具体的资源,其中包括这些基本细节吗。我用谷歌找不到他们!当您搜索套接字时,可能不会找到好的结果,因为套接字覆盖了广泛的协议,甚至包括无连接的协议。尝试搜索具体的协议。例如,当您在已建立的TCP连接上获得
SYN
时,会发生什么,有一个答案。
>>> 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)