Python 套接字编程-异常处理

Python socket programming - exception handling

我正在 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()

代码运行正常,但我不确定是否应该嵌套 try/catch 块?我是否也应该将 socket.socket 放入 try/catch 块中?

第二个问题,s.settimeout() 对我来说会怎样?据我了解文档,它会在 5 秒后抛出异常,但这是为了什么?只是 connect 还是会对 sendallrecv 做同样的事情?

由于您在所有异常块中执行完全相同的操作并捕获相同的 socket.error 异常,因此您可以放置​​ s.connects.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()

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

如果您确实打算以不同的方式处理每个错误,那么您可以像已有的那样将它们分开。 但请确保在异常块的末尾 break/return,这样您就不会尝试下一个。 socket examples,通过在循环中使用 continue

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

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

def socket_error_handler(exception, socket):
    #write error code to file
    etc.

Should I put socket.socket into try/catch block too?

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

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

第 2 部分:

s.settimeout(5.0) 设置每个套接字操作的超时时间,而不仅仅是第一次连接。也意味着它在 blocking mode.