2016-07-23 90 views
0

我正在研究一个基本的套接字客户端程序在Python中,我不完全确定如何处理异常。这是我到现在为止所做的: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

回答

2

既然你做的正是在所有异常块同样的动作和捕捉相同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块。如果你想做一些不同的事情,当你退出嵌套 - try时,你不能确定它已完成或引发异常的级别 - 需要使用标志值等来跟踪它。因此,对于你相同的错误处理代码的例子,起码,做这样的事情在你的except块:

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

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

我应该把socket.socket到try/catch块吗?

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

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

第2部分:

s.settimeout(5.0)设定每个插座操作超时,不只是第一次连接。也暗示它在blocking mode

+0

谢谢你这个伟大的答案!还有一个问题,当我使用原始版本(try/catch块一个接一个地)并且异常被socket.connect()捕获时会发生什么?我猜所有套接字操作都被执行了,这是不好的? –