2011-08-24 19 views
32

De la prueba, llegué a la conclusión de que en los siguientes tres casos volverá el socket.recv(recv_size).¿Cuándo regresa socket.recv (recv_size)?

  1. Después de que se cerró la conexión. Por ejemplo, el lado del cliente llamado socket.close() o se produjo un error de socket, devolvería cadena vacía.

  2. Algunos datos vienen, el tamaño de los datos es más que recv_size.

  3. Algunos datos vienen, el tamaño de los datos es menor que recv_size y no hay más datos después de un tiempo corto (encontré que 0.1s funcionarían).

Más detalles sobre # 3:

#server.py 

while True: 
    data = sock.recv(10) 
    print data, 'EOF' 

#client1.py 

sock.sendall("12345") 
sock.sendall("a" * 50) 

#client2.py 

sock.sendall("12345") 
time.sleep(0.1) 
sock.sendall("a" * 50) 

Cuando corro client1.py, los server.py Echos:

12345aaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaa EOF 

Cuando corro client2.py, los server.py Echos:

12345 EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 

¿Son correctas mis conclusiones? ¿Dónde puedo ver la descripción oficial sobre el # 3?

+0

http://docs.python.org/library/socket.html#socket.socket.recv – mouad

+7

Gracias, pero el manual no respondió mi pregunta. – redice

+3

Qué tal aquí: http://linux.die.net/man/2/recv – mouad

Respuesta

18

Sí, su conclusión es correcta. socket.recv es una llamada de bloqueo.

socket.recv(1024) leerá a lo sumo 1024 bytes, bloqueando si no hay datos esperando para ser leídos. Si no lee todos los datos, no se bloqueará ninguna otra llamada al socket.recv.

socket.recv también terminará con una cadena vacía si la conexión está cerrada o si hay un error.

Si desea un socket no bloqueante, puede utilizar el módulo de selección (un poco más complicado que el solo uso de sockets) o puede usar socket.setblocking.

Tuve problemas con socket.setblocking en el pasado, pero puede intentarlo si lo desea.

+0

No vi ninguna descripción oficial sobre mi conclusión 3). – redice

+0

socket.recv leerá lo que está listo para leer cuando se realiza la llamada a recv. No importa si la cantidad leída es menor que el tamaño máximo, el socket se desbloqueará tan pronto como pueda leer datos. – Martin

+1

También puede llamar a recv() como no bloqueante si le da la bandera correcta: 'socket.recv (10240, 0x40) # 0x40 = MSG_DONTWAIT aka O_NONBLOCK' Tenga en cuenta que debe detectar el ' [Errno 11 ] Recurso temporalmente no disponible' excepciones cuando no hay datos de entrada. – Ray

4

Tendrá el mismo comportamiento que la llamada recv libc subyacente, vea el man page para obtener una descripción oficial del comportamiento (o lea más general description de la aplicación sockets).

Cuestiones relacionadas