2013-02-20 47 views
1

我有以下代碼:如何在recv期間關閉TCP客戶端?

s.settimeout(300) 
while notend: 
    data = s.recv()  
    datacheck() 
    ... 

上面的代碼上的線程中運行,所以如果用戶設定的notend變量爲False線程將結束。但在這種情況下,它不會立即退出,因爲recv函數需要300秒退出。如何退出此線程?

# Wait all the threads 
for thread in threading.enumerate(): 
    if thread is not threading.currentThread(): 
     thread.join() 
+0

你確定這實際上是問題嗎? 'recv'需要一個參數:'socket.recv(bufsize)',否則會引發一個'TypeError'。你能告訴我們更多的代碼嗎? – msvalkon 2013-02-20 09:50:25

+0

是的緩衝區大小在那裏,我只是忘記包括在採樣代碼 – 2013-02-20 09:58:34

回答

1

答案很簡單 - 從另一個線程關閉S。 recv()調用將返回一個錯誤,因此允許調用它的線程清理並終止。

有沒有需要超時,選擇()等

+0

我剛剛測試過,它的工作正常,但我不得不使用'shutdown',因爲關閉沒有任何效果 – 2013-02-20 13:54:18

+0

感謝那個消息。關閉/關機/無論如何,只要它的工作正常,那我就可以! – 2013-02-20 15:40:53

0

利用socket.settimeout因爲recv是一個阻塞方法

+0

看起來他是:'s.settimeout(300)' – msvalkon 2013-02-20 09:46:24

+0

我知道這是一個阻塞功能,服務器有300秒開始發送測量數據,如果有超時,我將重新開始測量 – 2013-02-20 10:02:31

2

的問題是,如果你有一個阻塞套接字,recv()將爲超時的整個持續時間阻止。你可以指定一個較短的超時時間,但這可能不是你想要做的事情(如果ping實際上是幾千毫秒,那該怎麼辦?)。

而不是簡單地試圖recv()了一整天,你可以使用一個select.poll對象以更頻繁的速度(小於超時)輪詢感興趣的插座,並調用recv()只有當輪詢報告說,有一些數據讀。在民意測驗之間,如果你發現notend現在是虛假的,你可以跳出輪詢循環。

如果您的平臺不支持poll(),請查看它是否支持select()。然後,您可以使用select.select()函數來完成或多或少相同的任務。

下面是所描述的功能的引用:

http://docs.python.org/2/library/select.html#poll-objects http://docs.python.org/2/library/select.html#select.select

+0

我的問題是它只支持Unix系統'poll()系統調用,在大多數Unix系統上都支持' – 2013-02-20 10:00:48

+0

@iUngi你的平臺是否有'select() ?大多數平臺(包括Windows)都應該。 'select()'調用完成相同的任務,但語義略有不同。 (回答更新) – atomicinf 2013-02-20 10:03:51