【问题标题】:Simple two way socket communication简单的两路套接字通信
【发布时间】:2021-11-08 17:16:31
【问题描述】:

我想使用套接字在服务器和客户端之间实现简单的双向通信。客户端发送消息并等待回复。服务器读取消息并以适当的结果回复。我有以下代码,但它们都挂起。你能解释一下这里出了什么问题吗?

服务器:

import socket
import time

HOST = "127.0.0.1"
PORT = 18735

# create socket and listen
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen()
print(f"Listening on {HOST}:{PORT}")

# accept connection
conn, addr = s.accept()
print(f"Accepted connection from {HOST}:{PORT}")

cmd = ""
while True:
    data = conn.recv(2)
    time.sleep(1)
    if not data:
        break
    print(data.decode())
    # conn.sendall(b"OK")  This line fixes the problem!

conn.sendall(b"Finished")
s.close()

客户:

import socket

HOST = "127.0.0.1"
PORT = 18735

# create socket and connect
cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cs.connect((HOST, PORT))

# send data
cs.sendall(b"123456")

# wait for a result
data = cs.recv(1024)
print("result: ", data)
cs.close()

编辑: 现在,我可以通过从服务器发送短消息来解决问题。但是,我想知道这是否有必要?

【问题讨论】:

  • data = conn.recv(2) 将阻塞,直到从客户端接收到数据或客户端关闭连接(或其他一些网络错误)。服务器正在等待这种情况发生,但与此同时,客户端正在等待服务器发送一些东西。

标签: python sockets python-sockets


【解决方案1】:

在客户端断开连接或至少关闭其连接的写入部分(使用cs.shutdown(socket.SHUT_WR))之前,服务器不会脱离其while 循环。

客户端在收到来自服务器的消息之前不会断开连接,该消息是服务器在while 循环之外发送的(即在客户端断开/关闭其连接的写入部分之后)。

你已经创建了一个死锁。

从根本上说,问题在于,等到客户端断开连接后再向该客户端发送响应是没有意义的。要么客户端不需要期待回复,要么服务器需要在客户端仍然连接时发送它。对于后者,您可能需要实现以下其中一项:

  • 您正在实施的应用程序协议需要一个已定义的消息结构,以便服务器知道客户端何时完成发送。
  • 客户端需要一个可以发送的特殊序列来指示消息的结束。
  • 客户端需要关闭其连接的写入部分,以向服务器指示它不会再发送任何数据。

【讨论】:

  • 如果你看我的编辑,这个问题可以很容易地通过发回一些短信来解决。但是,我认为这是多余的。
  • 更新了我的答案以指明解决方案的方向,但我无法为您提供简单的解决方法。
  • 从技术上讲,在客户端关闭其连接的写入端之前,服务器不会中断。这可能发生在客户端调用cs.shutdown(socket.SHUT_WR) 之后,客户端仍然可以接收服务器发送的数据。
  • @PresidentJamesK.Polk 是的。我自己通常不会只关闭一个方向,所以我没有想到这一点。我会更新答案以提及它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多