如何在第一次请求后使用 Python 中的套接字修复聊天服务器中损坏的管道?
How to fix broken pipe in Chat server using socket in Python after first request?
我正在玩套接字并试图创建只有一个客户端连接的简单聊天服务器。代码和输出如下。
echo_server.py
import socket
host = ''
port = 4538
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
print "Starting Server"
while 1:
client, address = s.accept()
try:
data = client.recv(size)
if data is not None:
if data is 'q':
print "I received request to close the connection"
client.send('q')
continue
print "I got this from client {}".format(data)
client.send(data)
continue
if data == 0:
client.close()
finally:
client.close()
echo_client.py
import socket
host = ''
port = 4538
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
try:
while 1:
message = filename = raw_input('Enter a your message: ')
s.send(message)
data = s.recv(1024)
if data is 'q':
print "You requested to close the connection"
break
print "Received from socket {}".format(data)
finally:
s.close()
现在,我也尝试过使用 sendall() 但它不起作用。下面是两边的输出
客户:
Enter a your message: hello
Received from socket hello
Enter a your message: world
Received from socket
Enter a your message: hi
Traceback (most recent call last):
File "echo_client.py", line 12, in <module>
s.send(message)
socket.error: [Errno 32] Broken pipe
在服务器上
Starting Server
I got this from client hello
如您所见,服务器没有收到第二条消息(world)。并且什么都不回复,当我用 hi 向服务器发送第三个请求时,客户端以 Broken Pipe 终止
我该如何修复它?
编辑 1:
我更改了代码,现在如下。 s.accept() 卡在第二个请求中。以下是代码。
echo_server.py
import socket
host = ''
port = 4538
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
print "Starting Server"
try:
while 1:
print "BEFORE REQUEST"
client, address = s.accept()
print "AFTER REQUEST"
data = client.recv(size)
if data:
if data is 'q':
print "I received request to close the connection"
client.send('q')
print "I got this from client {}".format(data)
client.send(data)
else:
print "CLOSING IN ELSE"
client.close()
except:
print "CLOSING IN except"
client.close()
输出如下。
BEFORE REQUEST
AFTER REQUEST
I got this from client hello
BEFORE REQUEST
如您所见,第二次 accept() 从未 returns。如何让它发挥作用?
recv
returns 客户端关闭连接时的空字符串,而不是 None
或 0
。由于空字符串是 False 条件,只需使用 if data:
或 if not data:
.
而且,正如@JonClements 指出的那样,在服务器中使用 except
而不是 finally
,或者将 while
放在 try
和 if not data: break
退出 while
并执行 finally
。
我正在玩套接字并试图创建只有一个客户端连接的简单聊天服务器。代码和输出如下。
echo_server.py
import socket
host = ''
port = 4538
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
print "Starting Server"
while 1:
client, address = s.accept()
try:
data = client.recv(size)
if data is not None:
if data is 'q':
print "I received request to close the connection"
client.send('q')
continue
print "I got this from client {}".format(data)
client.send(data)
continue
if data == 0:
client.close()
finally:
client.close()
echo_client.py
import socket
host = ''
port = 4538
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
try:
while 1:
message = filename = raw_input('Enter a your message: ')
s.send(message)
data = s.recv(1024)
if data is 'q':
print "You requested to close the connection"
break
print "Received from socket {}".format(data)
finally:
s.close()
现在,我也尝试过使用 sendall() 但它不起作用。下面是两边的输出
客户:
Enter a your message: hello
Received from socket hello
Enter a your message: world
Received from socket
Enter a your message: hi
Traceback (most recent call last):
File "echo_client.py", line 12, in <module>
s.send(message)
socket.error: [Errno 32] Broken pipe
在服务器上
Starting Server
I got this from client hello
如您所见,服务器没有收到第二条消息(world)。并且什么都不回复,当我用 hi 向服务器发送第三个请求时,客户端以 Broken Pipe 终止 我该如何修复它?
编辑 1:
我更改了代码,现在如下。 s.accept() 卡在第二个请求中。以下是代码。 echo_server.py
import socket
host = ''
port = 4538
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
print "Starting Server"
try:
while 1:
print "BEFORE REQUEST"
client, address = s.accept()
print "AFTER REQUEST"
data = client.recv(size)
if data:
if data is 'q':
print "I received request to close the connection"
client.send('q')
print "I got this from client {}".format(data)
client.send(data)
else:
print "CLOSING IN ELSE"
client.close()
except:
print "CLOSING IN except"
client.close()
输出如下。
BEFORE REQUEST
AFTER REQUEST
I got this from client hello
BEFORE REQUEST
如您所见,第二次 accept() 从未 returns。如何让它发挥作用?
recv
returns 客户端关闭连接时的空字符串,而不是 None
或 0
。由于空字符串是 False 条件,只需使用 if data:
或 if not data:
.
而且,正如@JonClements 指出的那样,在服务器中使用 except
而不是 finally
,或者将 while
放在 try
和 if not data: break
退出 while
并执行 finally
。