2011-03-28 39 views
4

Python 2.7,Windows XP。我有一臺服務器將消息發送給客戶端。我使用select模塊檢查準備接收的套接字,以及捕獲特殊條件。我的印象是,如果客戶端關閉套接字,選擇()將在異常情況插座列表返回所述窩,但它似乎並沒有被這樣做:select.select()不會捕獲套接字上的異常情況嗎?

lin, lout, lex = select.select(socklist, socklist, socklist) 
for sock in lin: 
    # handle incoming messages 
for sock in lout: 
    # send updates 
for sock in lex: 
    # shut down server-side objects for particular client 

,會是什麼服務器確定客戶端是否仍連接的最佳方式?服務器並不總是發送數據,所以我不想依賴一個socket.send()來測試客戶端是否仍然存在。

回答

6

一個封閉的套接字不是一個例外(錯誤)條件。會發生什麼是套接字將在讀取列表(林),當你讀你會得到0字節。這意味着另一端已經關閉了插座。

更新

在正常實踐中你永遠不會看到任何東西,除了列表,並可以放心地忽略它。這是針對罕用的東西,如帶外(OOB)等。

回答質疑更新

可靠,快速地檢測到插座的另一端已經消失可能會非常棘手。如果能夠可靠地檢測到它是非常重要的,那麼應始終及時地採用更高級別的機制,例如keepalive/heartbeat。

如果客戶端乾淨地關閉套接字,那麼您應該在讀取列表中看到套接字。從套接字讀取將返回0字節,表示套接字已關閉(EOF)。

+0

這樣一個特殊的條件下將被關閉套接字中間傳輸呢? – 2011-03-28 23:19:39

+0

在這種情況下,如果我有一臺使用sock.send(msg)的服務器,我該如何判斷客戶端是否正在接收它?有沒有比settimeout()更好的方法? – 2011-03-28 23:20:44

+0

例外列表有點不恰當。據我所知,這隻適用於OOB(帶外)數據。 – kanaka 2011-03-28 23:23:44

1

關閉套接字的客戶端並不例外。事實上,除了特殊之外,您將在特殊條件列表中發現各種錯誤,但正確關閉的套接字不是其中之一。

+0

我編輯了我的問題。我將如何測試客戶端是否仍然連接?服務器可能並不總是在發送數據,所以我不想依賴socket.send()來檢測客戶端斷開並執行清理。 – 2011-03-28 23:28:02

2

套接字上「異常條件」的確切定義取決於底層實現。對於Windows XP,底層實現是WinSock select function,並且特殊條件包括:

  • 如果處理連接呼叫(非阻塞),連接嘗試失敗。
  • OOB數據可用於讀取
相關問題