2016-07-23 149 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()捕獲時會發生什麼?我猜所有套接字操作都被執行了,這是不好的? –