2013-06-30 40 views
13

我正在使用原始套接字接口(import socket)在Python 2.7.5中編寫應用程序。Python:檢測套接字何時因任何原因斷開連接?

我需要知道是否有方法可以註冊某種事件,或者如果TCP套接字連接仍然連接並建立,可以輕鬆地定期測試。

我發現的大部分建議都是這樣的:「只是嘗試從中讀取;如果它關閉,您將得到一個錯誤或沒有字節。」但是,有時候我還沒有準備好從它那裏獲得read,但我仍然想知道套接字是否已關閉,因此例如我可以立即手動重新連接。

此外,read從插座荷蘭國際集團將消除從緩衝區中讀取的字節數,所以read荷蘭國際集團只是爲了測試連接「活躍度」似乎並不可行。

有一個後臺線程來檢查連接的活躍性對我來說可以。該線程可以檢查每秒一次,看看連接是否存在;如果它被丟棄,那麼它可以調用一個函數,或設置一個變量或其他東西,以便應用程序知道連接關閉。知道它爲什麼關閉(通過同行重置,超時等)將更加有用....

對此有何建議?

+0

的流動;使用'select()'(或'epoll()'用於Linux) – tMC

+0

相關:http://stackoverflow.com/questions/17705239/is-there-a-way-to-detect-that-tcp-socket-has (TL; DR:除非你願意首先讀取來自套接字的所有字節,否則沒有好的辦法來確定連接是否已經關閉; TCP套接字是有意實現的,因爲它們基於FIFO事件排序的思想,即他們希望您按順序讀取傳入數據,並且只有在讀完所有數據後才能瞭解流結束) –

回答

13

使用select像本教程建議 http://docs.python.org/2/howto/sockets.html#non-blocking-sockets

如果插座是在輸出可讀的列表,你可以像關閉至一定-AS-WE-不斷得到功能於這這個套接字上的recv會返回一些東西。可寫列表的想法相同。你將能夠發送一些東西。也許不是你想要的,但有些事比沒有好。 (實際上,任何合理健康的套接字將返回爲可寫 - 這只是意味着出站網絡緩衝區空間是可用的。)

...如果在這些輸入列表中的某個地方是一個已經死亡的死亡選擇將失敗。

這是我通常在POSIX使用

import select 
import socket 

ip = '127.0.0.1' 
port = 80 

conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
conn.connect((ip, port)) 

while True: 
    try: 
     ready_to_read, ready_to_write, in_error = \ 
      select.select([conn,], [conn,], [], 5) 
    except select.error: 
     conn.shutdown(2) # 0 = done receiving, 1 = done sending, 2 = both 
     conn.close() 
     # connection error event here, maybe reconnect 
     print 'connection error' 
     break 
    if len(ready_to_read) > 0: 
     recv = conn.recv(2048) 
     # do stuff with received data 
     print 'received:', recv 
    if len(ready_to_write) > 0: 
     # connection established, send some stuff 
     conn.send('some stuff')