2012-05-22 91 views
0

我在使用select時遇到了問題。我只是想知道哪些客戶端仍然在那裏接收數據。這裏是我的代碼:這個基本的Python選擇在Windows上有什麼問題?

import socket, select 

server = socket.socket() 
server.bind(('localhost',80)) 
server.listen(1) 

answer = "HTTP/1.1 200 OK\r\n" 
answer+= "Content-type: text/plain\r\n" 
answer+= "Connection: close\r\n" 
body = "test msg" 
answer+= "Content-length: %d\r\n\r\n" % len(body) 
answer+= body 

clients = [] 

while True: 
    nextclient,addr = server.accept() 
    clients.append(nextclient) 
    clients = select.select([],clients,[],0.0)[1] 
    for client in clients: 
    client.send(answer) 

的選擇給我每次所有插座之前打開,即使連接在另一端封閉,這導致Errno1053:一個etablished連接是通過在軟件放棄了你主機。

我事先感謝您的幫助。

回答

1

您的選擇從不阻止。

超時值零指定一個輪詢並且永不阻塞。

此外,您的listen方法的論點是絕對極端的。

socket.listen(積壓)

偵聽到插座形成的連接。 backlog參數指定排隊連接的最大數量,並且至少應爲 ;最大值是系統相關的(通常爲5)

+0

這不是錯誤的原因。從1到5的積壓和select的不同超時有同樣的問題。無論如何,我不想在那裏有一個街區,我只想知道哪些客戶已經準備好寫作了。 – user1144442

0

據我所知,在寫入之後永遠不會關閉套接字,而且您也不會從clients中刪除套接字。

此外,您覆蓋clients,以便您的客戶端列表丟失;有些客戶永遠不會被處理。

喜歡的東西

clients_now = select.select([],clients,[],0.0)[1] 
    for client in clients_now: 
     client.send(answer) 
     client.close() 
     clients.remove(client) 

可能的幫助。

順便說一句,只是一個1或10毫秒的小塊將使您的服務器響應,但防止由於空閒等待而造成的高CPU負載。

BTW2:也許你應該包括你的服務器套接字在選擇過程以及...

+0

正常情況下,當我做客戶=選擇(..客戶..)我留在客戶端準備接收數據的客戶端。但事實證明,即使關閉套接字,我仍然保持每個客戶端都被接受。所以你的建議不會改變任何事情。此外,垃圾收集時,套接口會自動關閉。因此沒有準備好接收數據的套接字會在我的代碼中自動關閉。 – user1144442

+0

但是,如果您沒有收到關於對方是否已關閉的通知,那麼您將一直重複發送和發送相同的數據。另外,一個被延遲的客戶可能會因爲尚未準備好而過早退出客戶端。更好的方法是主動宣佈你已經完成了通過丟失套接字(這是很好的風格)並從要被觀察的列表中刪除來發送。 – glglgl