我有以下情况:
服务器
sock = socket.socket()
sock.bind((hostaddr, port))
sock.listen(backlog)
print(f'Server listenning on {hostaddr}:{port}')
while True:
client_sock, client_address = self.sock.accept()
print(f'Incoming connection from {client_address[0]}:{client_address[1]}')
while True:
data = client_socket.recv(buffer_size)
if not data:
break
print(f'Received "{data.decode()}" from {client_address[0]}:{client_address[1]}')
reply = f'Server: I got the message "{data.decode()}"'.encode()
client_socket.sendall(reply)
client_socket.close()
客户端
sock = socket.socket()
sock.connect(server_address)
sock.sendall('Lorem Ipsum'.encode())
while True:
data = sock.recv(buffer_size)
if not data:
break
print(data.decode())
sock.close()
我首先启动服务器,然后启动客户端,并获得以下日志:
服务器
Server listening on 172.16.0.110:8081
Incoming connection from 172.16.0.110:62388
Received "Lorem Ipsum" from 172.16.0.110:62388
客户端
Server reply: I got the message "Lorem Ipsum"
我想得到服务器的回复,然后客户端应该完成,但服务器和客户端都进入了无限循环,并一直运行。为什么以及如何解决这个问题?我在IPv4网络中的Windows10 x64上使用Python3.6.0。
发布于 2017-09-03 07:55:22
您必须定义一个协议,该协议只是如何交换和格式化消息以及如何传递消息边界的规则。看起来您只是想让客户端发送一些数据并读取服务器响应。您可以通过关闭客户端连接的写入部分来实现这一点,在本例中,可以在sock.sendall(...)
之后调用sock.shutdown(socket.SHUT_WR)
。
在服务器端,这是同一连接的读取部分,服务器将其检测为EOF,从而导致socket.recv()
返回一个长度为零的字节对象。
对于需要在同一连接上发送多条消息的更复杂的协议,必须使用不同的策略。二进制协议的一个简单示例是发送4个字节,表示消息的字节长度,然后为后续消息本身发送该多个字节。
发布于 2017-09-03 07:18:26
一种方法是为套接字设置超时,以便在等待回复时不会永远阻塞,使用socket.settimeout()
,如下所示:
sock = socket.socket()
sock.connect(server_address)
sock.sendall('Lorem Ipsum'.encode())
sock.settimeout(5.0) # sets timeout to 5 seconds
while True:
data = sock.recv(buffer_size)
if not data:
break
print(data.decode())
sock.close()
https://stackoverflow.com/questions/46018926
复制相似问题