简单的双向套接字通信

Simple two way socket communication

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

服务器:

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()

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

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

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

你造成了僵局。

从根本上说,问题是等到客户端断开连接后再向该客户端发送响应是没有意义的。客户端不需要期望返回响应,或者服务器需要在客户端仍处于连接状态时发送它。对于后者,您可能需要执行以下操作之一:

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