2013-02-13 2 views
2

Вы знаете, почему этот цикл не прерывается?python: loop with socket.recv()

#!/usr/bin/env python 

from socket import * 
import os 
import sys 

if __name__ == '__main__': 
HOST = '127.0.0.1' 
PORT = 55554 

print 'Creating socket' 
socketProxy = socket(AF_INET, SOCK_STREAM) 

print 'bind()' 
socketProxy.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 
socketProxy.bind((HOST, PORT)) 

print 'Waiting for connection request' 
socketProxy.listen(1) 
conn, addr = socketProxy.accept() 

print 'Connected to ', addr 

request = '' 

while True: 
    data = conn.recv(16); 
    if not data: break 
    request = request+data 


print request 
sys.stdout.flush() 

Я пишу немного сервера прокси получать запросы, которые могут быть произвольно долго, так что я должен ждать, пока я не получил всю эту просьбу. В любом случае этот цикл (когда len (data) == 0) не останавливается, и он продолжает ждать. Как я могу остановить его? Thanks

+3

Клиент не выключает/закрывает сокет, может быть? –

+1

Вы уверены, что это не просто зависает на 'conn.recv (16)', потому что сокет не получает никаких данных? – sloth

+0

Да, клиент не закрывает сокет, потому что он ждет ответа ... – user1576208

ответ

1

Одно из решений - сделать сокет неблокирующим. Затем вы получаете в цикле, пока не будет получено больше данных. Если данные не получены (т. Е. request пуст), то соединение было закрыто, в противном случае у вас есть запрос.

Если у вас есть запрос, отправьте его на фактический сервер и выполните то же самое, что и выше, в ожидании ответа. Отправьте ответ клиенту.

+0

Должен ли я использовать MSG_DONTWAIT для блокировки сокета? – user1576208

+1

@ user1576208 Или используйте метод ['socket.setblocking'] (http://docs.python.org/2/library/socket.html#socket.socket.setblocking). –

+0

Клиент может занять некоторое время для отправки каких-либо данных в сокет, что означает, что соединение не закрыто, но данные не принимаются в момент вызова recv(). Вы должны убедиться, что протокол имеет какой-то способ обнаружения через сообщение, когда клиент завершает соединение. – Gustavo6046