Python 客户端关闭时服务器崩溃

Python 客户端关闭时服务器崩溃,python,sockets,networking,client-server,Python,Sockets,Networking,Client Server,今天早些时候我遇到了这个问题。这是我的第一个网络应用程序 server.py #!/usr/bin/python # -*- coding: utf-8 -*- import socket s = socket.socket() host = socket.gethostname() # Reserve a port for your service. port = 12345 # Bind to the port s.setsockopt(socket.SOL_SOCKET, socke

今天早些时候我遇到了这个问题。这是我的第一个网络应用程序

server.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

import socket

s = socket.socket()
host = socket.gethostname()

# Reserve a port for your service.
port = 12345
# Bind to the port
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))

# Now wait for client connection.
s.listen(1)
conn, addr = s.accept()
try:
    while True:
        # connection, address
        content = conn.recv(1024)
        if content in ('status', 'stop', 'start', 'reload', 'restart'):
            conn.send('%s received' % content)
        else:
            conn.send('Invalid command')
except KeyboardInterrupt:
    conn.close()
    s.shutdown(socket.SHUT_RDWR)
    s.close()
#!/usr/bin/python
# -*- coding: utf-8 -*-

import socket

s = socket.socket()
host = socket.gethostname()
port = 12345

s.connect((host, port))
try:
    while True:
        print ''
        value = raw_input('Enter a command:\n')
        if value != '':
            s.send(value)
            print s.recv(1024)
except KeyboardInterrupt:
    s.shutdown(socket.SHUT_RDWR)
    s.close()
client.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

import socket

s = socket.socket()
host = socket.gethostname()

# Reserve a port for your service.
port = 12345
# Bind to the port
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))

# Now wait for client connection.
s.listen(1)
conn, addr = s.accept()
try:
    while True:
        # connection, address
        content = conn.recv(1024)
        if content in ('status', 'stop', 'start', 'reload', 'restart'):
            conn.send('%s received' % content)
        else:
            conn.send('Invalid command')
except KeyboardInterrupt:
    conn.close()
    s.shutdown(socket.SHUT_RDWR)
    s.close()
#!/usr/bin/python
# -*- coding: utf-8 -*-

import socket

s = socket.socket()
host = socket.gethostname()
port = 12345

s.connect((host, port))
try:
    while True:
        print ''
        value = raw_input('Enter a command:\n')
        if value != '':
            s.send(value)
            print s.recv(1024)
except KeyboardInterrupt:
    s.shutdown(socket.SHUT_RDWR)
    s.close()
它是一个非常基本的客户机/服务器应用程序。服务器启动,并等待 客户端发送命令。客户端连接到服务器,要求用户 键入命令。然后将命令发送到服务器,服务器将回复

接收到
无效命令
。 代码运行得很好,直到我按了
CTRL
+
C
。服务器崩溃了。为什么呢

例如:

python client.py 

Enter a command:
stop
stop received

Enter a command:
status
status received

Enter a command:
bla
Invalid command

Enter a command:
^C
在服务器端:

python server.py 
Traceback (most recent call last):
  File "server.py", line 25, in <module>
    conn.send('Invalid command')
socket.error: [Errno 32] Broken pipe
python服务器.py
回溯(最近一次呼叫最后一次):
文件“server.py”,第25行,在
conn.send('无效命令')
socket.error:[Errno 32]管道破裂

基本上,我并没有在我的服务器上为将来的新客户端重新创建新连接,然后,当它碰到行
conn.send('Invalid command')
时,它崩溃了。要解决这个问题:

我刚刚替换了:

conn.send('Invalid command')
与:


将您的
接受也放入while循环中。比如:

while True:
    conn, addr = s.accept()        # accept one connection.
    while True:                    # Receive until client closes.
        content = conn.recv(1024)  # waits to receive something.
        if not content:            # Receive nothing? client closed connection,
            break                  #   so exit loop to close connection.
        if content in ('status', 'stop', 'start', 'reload', 'restart'):
            conn.send('%s received' % content)
        else:
            conn.send('Invalid command')
    conn.close()                   # close the connection 

另请注意,当客户端关闭连接时,
recv
返回空字符串,因此,
if not content:break

您是否知道,
套接字.send
不保证发送您传递给它的整个字符串?因为我只读取1024字节?如果是,我知道,但我只读了几个字符,所以这并不重要。如果你不在乎你的应用程序是否可靠,那也没关系。:)许多路由器可以并且将把1024字节(或更少)的TCP流量分割成多个IP数据报。另外还有另一个bug,那就是您的协议没有帧:没有任何东西可以阻止您的服务器由于一次读取而意外地获得“statusstop”。你可能想通过阅读了解更多!为什么这比一个
try/except
语句要好?你能说得更具体些吗?否则,感谢您提供更流畅的代码流。不重复(在两个地方接受)。更清晰的意图。建立连接,接收数据直到客户端关闭,关闭连接并重复。我没有得到的部分是:如果内容为“”,则表示客户端关闭连接。感谢阅读
socket.recv
文档。对于同步连接,
recv
将等待至少一个字节的数据准备就绪,但如果客户端关闭连接,将返回零字节(空字符串)。非常感谢,这对我帮助很大