gpt4 book ai didi

Python客户端套接字正在连接,即使服务器不接受新连接并且积压大小为0

转载 作者:行者123 更新时间:2023-12-03 12:02:43 24 4
gpt4 key购买 nike

我目前正在python中试验套接字。我尝试了以下 3 个变体(跳过代码先阅读问题):

class Server(threading.Thread):

def __init__(self):
super(Server, self).__init__()
self.ip = "localhost"
self.port = 23071
self.connectionNumber = 0

def run(self):
self.server= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.ip, self.port))
self.server.listen(self.connectionNumber)

print("SERVER: Server is running")

print("SERVER: Waiting for connection")
client, addr = self.server.accept()
print("SERVER: Something connected at {}".format(addr))

time.sleep(10) # Simulating doing something

client.close()
self.server.close()
print("Server is closed")

class Client(threading.Thread):

def __init__(self):
super(Client, self).__init__()
self.ip = "localhost"
self.port = 23071

def run(self):
time.sleep(3) #Ensure the client socket is created after the server socket

self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
print("CLIENT. Trying to connect")
self.server.connect((self.ip, self.port))
print("CLIENT. Connection sucessful")

time.sleep(2) # SImulating doing something
except Exception as e:
print("CLIENT: Exception \"{}\" happend".format(e))
finally:
self.server.close()
print("CLIENT: Socket closed")

if __name__ == "__main__":
server = Server()
client = Client()

server.start()
client.start()

server.join()
client.join()
class Server(threading.Thread):

def __init__(self):
super(Server, self).__init__()
self.ip = "localhost"
self.port = 23071
self.connectionNumber = 0

def run(self):
time.sleep(3) #Ensure server socket is created after client socket
self.server= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.ip, self.port))
self.server.listen(self.connectionNumber)

print("SERVER: Server is running")

print("SERVER: Waiting for connection")
client, addr = self.server.accept()
print("SERVER: Something connected at {}".format(addr))

time.sleep(10) # Simulating doing something

client.close()
self.server.close()
print("Server is closed")

class Client(threading.Thread):

def __init__(self):
super(Client, self).__init__()
self.ip = "localhost"
self.port = 23071

def run(self):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
print("CLIENT. Trying to connect")
self.server.connect((self.ip, self.port))
print("CLIENT. Connection sucessful")

time.sleep(2) # SImulating doing something
except Exception as e:
print("CLIENT: Exception \"{}\" happend".format(e))
finally:
self.server.close()
print("CLIENT: Socket closed")
class Server(threading.Thread):

def __init__(self):
super(Server, self).__init__()
self.ip = "localhost"
self.port = 23071
self.connectionNumber = 0

def run(self):
self.server= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.ip, self.port))
self.server.listen(self.connectionNumber)

print("SERVER: Server is running")

#Ensure the server socket is created when the client wants to make a connection
#but the server isn't waiting for new connections when the client establishes a connection
#(.accept() call delayed)
time.sleep(3)

print("SERVER: Waiting for connection")
client, addr = self.server.accept()
print("SERVER: Something connected at {}".format(addr))

time.sleep(10) # Simulating doing something

client.close()
self.server.close()
print("Server is closed")

class Client(threading.Thread):

def __init__(self):
super(Client, self).__init__()
self.ip = "localhost"
self.port = 23071

def run(self):
time.sleep(1) #Ensure client socket is created after server socket
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
print("CLIENT. Trying to connect")
self.server.connect((self.ip, self.port))
print("CLIENT. Connection sucessful")

time.sleep(2) # SImulating doing something
except Exception as e:
print("CLIENT: Exception \"{}\" happend".format(e))
finally:
self.server.close()
print("CLIENT: Socket closed")

if __name__ == "__main__":
server = Server()
client = Client()

server.start()
client.start()

server.join()
client.join()

在第一个变体中,可以毫无问题地建立连接。我希望它是这样的,因为服务器正在等待与 .accept() 的新连接。在第二个变体中,由于还没有服务器套接字,因此无法建立连接。连接无法到达目标(发生异常。WinError 1106..something)。也是意料之中。但是第三个让我很困惑。我预计无法建立连接,因为存在服务器套接字,但服务器尚未接受新连接(未调用 .accept() )和最大值。积压中的连接数为 0 (.listen(0))。客户端的 .connect() 调用仍然没有阻塞也没有抛出异常。它指出:“客户:连接成功”。发生了什么事?我预计调用会阻塞,因为我从未指定超时并且永远不会接受连接。

我希望你们中的某个人可以向我详细解释发生了什么。我在 Stackoverflow 和其他方面在这里找到了类似的主题,但我还没有找到摆脱我困惑的答案。

问候,
三镜

编辑:

经过对wireshark的进一步调查,我发现了以下内容:
  • server.listen(x) “启动”套接字。从此时起,服务器套接字可以通过响应客户端发起的三向握手来执行三向握手。
  • server.listen(x) 在 backlog 中最多允许 x 个元素。这意味着最多 x 个元素可以执行三次握手。在执行后或执行期间,它们会在积压中排队。如果服务器套接字调用 .accept(),它们会从 backlog 中取出。因此,积压队列总是包含已经执行 3 次握手或当前正在执行的客户端连接。 x 确定此积压队列的大小。
  • 似乎 server.listen(0) 与 server.listen(1) 具有相同的效果。只有一个连接能够执行 3 次握手并包含在积压队列中。因此我的猜测是,python 套接字实现是,.listen(...) 必须有一个至少为 1 的参数值。我猜如果它更低,它会被调整为 1。

  • 因此,我想稍微改变一下我的问题。现在很明显为什么 socket.connect() 不抛出异常或阻塞。它可以成功地执行 3 次握手并且连接是打开的。但是 socket.accept() 会做什么呢?它显然从积压队列中取出了一个元素,但是就服务器和客户端之间的通信以及 tcp 协议(protocol)而言,这意味着什么?

    最佳答案

    But what does socket.accept() do then? It obviously takes one element out of the backlog queue, but what does it mean in terms of communication between server and client and in terms of the tcp protocol?



    它在服务器和客户端之间的通信以及 tcp 协议(protocol)方面没有任何作用。它只是将进程的文件描述符与连接相关联,即。 e.它设置操作系统数据结构。我们可以通过 netstat 看到效果, 即G。在带有 -b 的 Windows 上或 -o选项。

    关于Python客户端套接字正在连接,即使服务器不接受新连接并且积压大小为0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62029533/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com