Python套接字编程-异常处理

Rok*_*nar 2 python sockets client tcp

我正在用 python 开发一个基本的套接字客户端程序,但我不完全确定如何处理异常。这就是我到目前为止所做的:

TCP_IP      = '..............'
TCP_PORT    = 4950
MESSAGE     = "o3"
BUFFER_SIZE = 2048
data        = ""

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.settimeout(5.0)

try:
    s.connect((TCP_IP, TCP_PORT))
except socket.error:
    #write error code to file
    s.close()

try:
    s.sendall(MESSAGE)
except socket.error:
    #write to file or whatever
    s.close()

try:
    data = s.recv(BUFFER_SIZE)
except socket.error:
    #write to file or whatever
    s.close()

finally:
    s.close()
Run Code Online (Sandbox Code Playgroud)

代码按我想要的方式工作,但我不确定是否应该嵌套 try/catch 块?我socket.socket也应该放入 try/catch 块吗?

第二个问题,s.settimeout()我的情况该怎么办?据我理解的文档,它会在 5 秒后抛出异常,但为什么呢?只是或者它会对andconnect做同样的事情吗?sendallrecv

ane*_*oid 5

由于您在所有异常块中执行完全相同的操作并捕获相同的socket.error异常,因此您可以将s.connect,s.sendalls.recv放在同一个try:块中。就像这样:

try:
    s.connect((TCP_IP, TCP_PORT))
    s.sendall(MESSAGE)
    data = s.recv(BUFFER_SIZE)
except socket.error:
    #write error code to file
finally:
    s.close()
Run Code Online (Sandbox Code Playgroud)

请注意,由于s.close也在finally您的示例中的部分中,因此即使在发生异常之后,它也始终会被调用。因此,当您尝试关闭已关闭的套接字时,最终会发生另一个异常。通过不将其放入except块中而仅放入 中finally,您可以避免这种情况。

如果您确实打算以不同的方式处理每个错误,那么您可以像已有的那样将它们分开。但请确保break/return位于异常块的末尾,这样您就不会尝试下一个。在套接字示例中,通过continue在循环中使用 a来完成此操作。

如果您想在异常块中执行不同的操作,则嵌套它们会有所帮助。except但如果不是的话,你每次都会重复这个块。如果您想做一些不同的事情,当您退出嵌套时try,您将无法确定它已完成哪个级别或引发异常 - 需要使用标志值等来仅跟踪它。因此,对于相同错误处理代码的示例,至少在您的except块中执行类似的操作:

except socket.error as e:
    socket_error_handler(e, s)

def socket_error_handler(exception, socket):
    #write error code to file
    etc.
Run Code Online (Sandbox Code Playgroud)

socket.socket也应该放入 try/catch 块吗?

他们在上面链接的示例中这样做了。

除了日志记录之外,您不应该在每个阶段都进行相同的异常处理。可能需要单独处理这些。

第2部分:

s.settimeout(5.0)设置每个套接字操作的超时,而不仅仅是第一个连接。也意味着它处于阻塞模式