首页 > 解决方案 > 如何正确处理套接字异常

问题描述

在我的 Python 程序中,我有一个侦听传入连接的套接字,当我在其上运行nmap时,它会突然关闭,因为它会在扫描端口时重置连接。

我尝试在except: pass代码末尾放置一个块,以及以下内容:

if __name__ == "__main__":
    try:
        listen()
    except KeyboardInterrupt:
        pass

但是在收到连接重置后,它不会通过。它只是关闭程序而不打印任何内容。我该如何解决这个问题?服务器端代码负责接收和处理信息。我应该在块之后放一些东西while,还是只是一个except

connection.listen(10)
while True:
    current_connection, address = connection.accept()
    current_connection.send('Input:')
    while True:
        data = current_connection.recv(2048)

错误:

Traceback (most recent call last):
  File "server.py", line 41, in <module>
    listen()
  File "server.py", line 12, in listen
    current_connection.send('Input:')
socket.error: [Errno 104] Connection reset by peer

标签: pythonsockets

解决方案


您的代码的结构方式,如果您将 aexcept: pass放在顶层,那么当异常发生时,它只会被困在顶层,并且您的代码中没有任何内容会导致它回到您的listen..accept代码中。相反,您应该在代码中的正确位置捕获异常,以便您的代码继续外while True循环。

一般来说。将所有通常可能失败的套接字操作放在 try-except 块中是个好主意。但是,在 python 中,裸露被认为是不好的做法except——因为裸露except往往会隐藏代码中不应隐藏的错误。因此,您通常会执行以下操作:

connection.listen(10)
while True:
    current_connection, address = connection.accept()
    try:
        current_connection.sendall('Input:')
        while True:
            data = current_connection.recv(2048)
            if data == '':
                break          # End of file (peer socket was closed)
    except socket.error as sockerr:
        print("Socket exception on send/recv", sockerr)
    current_connection.close()

另外,请注意我替换sendsendall. 这样可以确保发送整个字符串。(使用send,在某些情况下发送的字节数少于整个字符串是有效的。)


推荐阅读