Sockets en Python

Buenasss,

para los expertos en Python, cómo gestionais la recepción
de un paquete a través de un socket, si éste supera el
tamaño del buffer? He leído por ahí que hay varios métodos,
como el de recibir primero el tamaño del envío, y en la
segunda parte recibir el resto de la trama en un bucle, o
algo así ... ¬_¬

Una ayudita, pliz?

Thnks
A ver, no conozco eso que dices de enviar primero el tamaño y luego los datos, lo que se suele hacer (o lo que yo he aprendido vaya) es hacer un bucle infinito para recoger todos los datos, por ejemplo:


while 1:
   try:
      buf = self.sock.recv(2048)
   except socket.error, e:
      # pass
   if not len(buf): # if the buffer is empty
      break
   result += buf


vamos, un bucle infinito donde vas leyendo por bloques, en este caso 2 kb, y lo vas metiendo en una variable, asi hasta que leas todo.


Espero que te sea de ayuda.
Como no te puede llegar paquetes mayores que el MTU haz lo que te dice Fox con el MTU como tamaño del buffer.
No sé qué c*ñ* había leído ayer, pero parece una solución
bien sencilla! Pero en todo caso, son bloques de 2 Mb o 2Kb?

Gracias a los dos!
El parámetro es el tamaño de los datos a recibir en bytes. Luego son 2 KB
OK!

habeis leído algo sobre un exploit que afecta a los
sockets de python y perl, usando un buffer underrun?
Como no te puede llegar paquetes mayores que el MTU haz lo que te dice Fox con el MTU como tamaño del buffer.


Esto no es cierto. O mejor dicho, es cierto que no llegarán paquetes mayores que la MTU, lo que no es cierta es la suposición de que el 'revc' se ejecutará cada vez que haya datos disponibles.

- ferdy
Perdona Ferdy pero no entiendo a qué te refieres. Cuando llamas a recv este se bloquea hasta que haya datos disponibles o hasta que se cierre el otro lado, lo que antes ocurra.
Lo que no significa que cuando vuelva el recv haya como mucho MTU bytes para leer.

- ferdy
Estooo, ahora me he perdido! Quieres decir que si
el paquete es mayor que el MTU, la segunda vez que
se ejecute el loop puede que no haya nada para
recibir?
No, y no soy capaz de saber cómo has podido llegar a esa conclusión :)

Es simple, recv puede tener disponibles más de MTU bytes para leer.

- ferdy
Ferdy escribió:No, y no soy capaz de saber cómo has podido llegar a esa conclusión :)

Es simple, recv puede tener disponibles más de MTU bytes para leer.

- ferdy


JAJAJA, es fácil: con mucha imaginación! jaja ;-)

Zenks por la respuesta

Enzo
Y la razón es (explicación SUPER-simplificada, OJO!):

1) El sitema operativo mantiene buffers internos y no 'te da' datos hasta que no los llena. (más o menos)

2) No debes asumir que tu proceso es el único en el sistema. Cuando haces recv entras en una cola de bloqueados, cuando el SO recibe paquetes de la red te saca de esa cola y te mete en la de 'listos'. Desde que estás 'listo' hasta que REALMENTE te ejecutas, pueden llegar MUCHÍSIMOS paquetes de red (y más con las Gigabit y 10Gigabit de hoy en día).

Hay más casos, pero eso resume los mayores (o eso creo)

- ferdy
Gracias por la fácilaclaración, Ferdy!

Pero supongo que el ejemplo del loop para ir leyendo
el paquete por trozos es válido y no recibiré otros
datos que no pertenezcan a otro socket, no?

Saludos
Yo creo que no habeis notado cierto problema. En esa conexión, ¿el que te envia los datos va a cerrar la conexión ? por que si no lo hace, te quedarás esperando hasta el fin de los tiempos.

Por otro lado, no es bueno utilizar el concepto de paquete con TCP, en TCP tienes un stream, nadie te garantiza que recv te devuelva tantos datos como le has pedido, aunque haya dicha cantidad de datos en el buffer. Por eso en los protocolos como dios manda(ej: HTTP), se señaliza el final de cada "mensaje", asi como el inicio.

Además esta el caso que dijo ferdy, que ha quedado explicado perfectamente :).
14 respuestas