2013-09-01 157 views
4

我有一個python tcp服務器,每個連接都有線程監聽。 當我打電話給close關於連接對象異常「壞文件描述符」被拋出。 通過Google搜索,我發現了一些解決方案,每個解決方案都使用循環來接收客戶端數據,並在他們決定斷開客戶端時打破該循環。我的客戶端是用C#編寫的,沒有「獲取」,它與服務器「斷開連接」,python只是忽略來自C#客戶端的輸入數據。 在python中斷開tcp連接與服務器端的最佳實踐方法是什麼?Python關閉tcp連接

在此先感謝

+0

//,優秀的問題!我其實對此很感興趣。 (http://superuser.com/questions/127863/manually-closing-a-port-from-commandline/946641?noredirect=1#comment1429085_946641)你介意顯示一個或兩個「循環「解決方案,你在搜索引擎上找到? –

回答

2

一個壞的文件描述符,最有可能的,意味着該插座已經被另一個線程關閉。

以下是關於一般實踐的一些想法。對於客戶端來說,知道它斷開連接的一種方法是檢查recv()值是否爲0.如果是,則表示遠程端已關閉連接。基本上,您應該使用select(或poll)並將所有客戶端和服務器的fds傳遞給select。如果你在任何一個fds上都有讀取事件,那麼根據fd類型,這裏會發生什麼。如果fd是服務器類型,那麼讀取事件意味着存在未決連接,您應該發出accept()來獲取新連接。另一方面,如果hte fd是非服務器類型(意思是一個常規的tcp連接),那麼read事件意味着有一些數據,你應該發出一個recv()事件來讀取數據。

您將使用循環選擇。基本上,使用select()調用啓動循環,一旦你得到一個事件,就對該事件做一些事情,然後重新進入循環併發出下一個select()。 您可能會發現這些鏈接有幫助的:http://ilab.cs.byu.edu/python/select/echoserver.htmlhttp://docs.python.org/2/library/socket.html

1

the docs

注:關閉()釋放與連接相關聯的資源,但 並不一定立即關閉連接。如果您想要 及時關閉連接,請在 close()之前調用shutdown()。

所以你應該在致電close()之前致電shutdown()。你還應該通過SHUT_RDWR標誌完全關閉連接:

from socket import SHUT_RDWR 
... 
try: 
    s.shutdown(SHUT_RDWR) 
    s.close() 
except Exception: 
    pass 

「壞文件說明」錯誤的手段(最有可能)的插座已關閉(至少從Python端)。