Ver Mensaje Individual
  #5 (permalink)  
Antiguo 10/04/2009, 04:49
Avatar de chuidiang
chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Respuesta: Escribir al mismo tiempo en el mismo socket

Hola:

Un socket tiene internamente dos buffers de bytes, uno para lectura y otro para escritura.

Cuando un hilo escribe, realmente está situando bytes en ese buffer y el sistema operativo se encargará de ir enviando esos bytes por el canal hacia el otro ejecutable. Si varios hilos escriben a la vez, van metiendo entremezclados sus bytes en ese buffer, por eso es necesario sincronizar las escrituras.

En la lectura, el sistema operativo va dejando los bytes que recibe en un buffer de lectura. Cuando un hilo lee, está retirando los bytes del buffer, por lo que otro hilo no va a poder leer lo mismo. Si dos hilos intentan leer a la vez, puede que uno se quede con parte de los bytes y otro con otra parte. Por ello, las lecturas también deben estar sincronizadas.

Los bufferes de escritura y lectura son independientes, por lo que un hilo podría escribir y otro leer a la vez sin sincronización y no habría problemas. Por ello, realmente debes usar para sincronizar los OutputStream para los hilos que escriben y los InputStream para los que leen.

En el caso del cliente, al leer los hilos sincronizadamente, no tienes garantía ninguna de que cada uno lea el mensaje que le corresponde y si lee un mensaje que no es para él, al retiralo del buffer, el otro hilo ya no lo encontrará. No funciona por tanto que varios hilos lean de un mismo socket. En java tienes opciones para "ver" que tiene el buffer de lectura sin retirarlo, por lo que los hilos podrían, sincronizadamente, mirar ese buffer para ver si lo que hay es para él y así retirarlo o no. De todas formas, no suele usarse esta opción, ya que la gestión suele ser compleja.

Lo suyo es hacer un único hilo que extraiga los mensajes del socket y los vaya repartiendo, o bien que cada hilo abra su propio socket con el servidor. Se suele elegir una opción u otra en función de la cantidad de mensajes, cantidad de hilos, si comparten o no muchos mensajes, etc.

- Si hay pocos hilos cliente y el funcionamiento es petición del cliente-respuesta del servidor, es mejor que cada uno abra su propio socket.

- Si hay muchos hilos y van a tener muchos mensajes compartidos y el servidor puede a veces enviar mensajes sin necesidad de que el cliente lo pida, entonces es mejor un único hilo cliente que vaya repartiendo mensajes a los demás.

El motivo de estas decisiones es, por un lado, que no se pueden mantener simultáneamente muchos descriptores de fichero abiertos (sockets), el sistema operativo no lo permite. Si hay muchos hilos (alrededor de 64 o más), el sistema operativo no te permitirá abrir tantos sockets simultáneamente.

Por otro lado, si la relación cliente-servidor es petición-respuesta, es mejor que cada uno tenga su propio socket, ya que así cada hilo sólo recibirá lo que ha pedido. El que "reparte" no tendrá que saber quién ha pedido algo ni pasará mensajes innecesariamente a los hilos que no lo necesitan. Sin embargo, si el servidor puede enviar cosas por su cuenta que pueden interesar a varios hilos, es mejor un único socket, evitando al servidor tener que enviar el mensaje muchas veces por todos los sockets abiertos.

Se bueno.
__________________
Apuntes Java
Wiki de Programación