如何在第一次请求后使用 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 客户端关闭连接时的空字符串,而不是 None0。由于空字符串是 False 条件,只需使用 if data:if not data:.

而且,正如@JonClements 指出的那样,在服务器中使用 except 而不是 finally,或者将 while 放在 tryif not data: break 退出 while 并执行 finally