c++ - servidor - socket udp java
leer y escribir simultáneamente en el mismo socket en C o C++ (3)
En el escenario anterior, ¿se requiere algún tipo de bloqueo?
Ninguna.
¿El escenario anterior requiere un socket sin bloqueo?
Es posible que lo poco que le preocupa -los hilos de lectura y escritura en una conexión establecida- no tenga que ser no bloqueante si está contento de que esos hilos estén esperando allí para completarse. Esa es normalmente una de las razones por las que usarás hilos en lugar de seleccionar o sondear o realizar operaciones asincrónicas ... también simplifica el código.
Si el hilo que acepta nuevos clientes está contento de bloquear en la llamada para accept()
, entonces usted está bien allí también.
Aún así, hay un problema sutil con los servidores TCP que quizás desee tener en mente ... si su programa crece para manejar múltiples clientes y tener algunas tareas domésticas periódicas para hacer. Es natural y tentador usar una instrucción select
con un tiempo de espera para verificar la legibilidad en el socket de escucha, que indica un intento de conexión del cliente, y luego accept
la conexión. Hay una condición de carrera allí: el intento de conexión del cliente puede haber caído entre select()
y accept()
, en cuyo caso accept()
bloqueará si el socket de escucha no es no-bloqueante, y eso puede evitar un retorno oportuno a la select()
repite y detiene el procesamiento periódico de tiempo de espera hasta que otro cliente se conecta.
¿Hay alguna biblioteca de código abierto que pueda ayudar en el escenario anterior?
Hay cientos de bibliotecas para escribir servidores básicos, pero en última instancia lo que usted solicitó se logra fácilmente encima de los zócalos BSD proporcionados por el sistema operativo o su bastardización de Windows.
Estoy implementando un servidor simple, que acepta una sola conexión y luego usa ese socket para leer y escribir mensajes de los hilos de lectura y escritura simultáneamente. ¿Cuál es la forma más segura y fácil de leer y escribir simultáneamente desde el mismo descriptor de socket en c / c ++ en Linux? No necesito preocuparme por la lectura y escritura de múltiples hilos desde el mismo zócalo, ya que habrá una única lectura dedicada y una sola escritura dedicada de escritura en el zócalo.
En el escenario anterior, ¿se requiere algún tipo de bloqueo?
¿El escenario anterior requiere un socket sin bloqueo?
¿Hay alguna biblioteca de código abierto que pueda ayudar en el escenario anterior?
Los enchufes son BI-DIRECCIONALES. Si alguna vez diseccionó un cable de Ethernet o serie o si vio el diagrama de cableado de hardware de bajo nivel para ellos, puede VER cables de cobre distintos para las líneas "TX" (transmitir) y "RX" (recibir). El software para enviar las señales, desde el controlador del dispositivo hasta la mayoría de las API del sistema operativo para un ''socket'', refleja esto y es la diferencia clave entre un socket y un conducto ordinario en la mayoría de los sistemas (por ejemplo, Linux).
Para aprovechar al máximo los sockets, necesitas:
1) Soporte Async IO que usa IO Completion Ports, epoll (), o algún sistema asincrónico de devolución de llamada o evento para ''despertar'' cada vez que los datos entran en el socket. Luego debe llamar a su API de "nivel más bajo" ReadData para leer el mensaje de la conexión de socket.
2) Una segunda API que admite las escrituras de bajo nivel, un ''WriteData'' (transmitir) que empuja los bytes al socket y no depende de nada que la lógica de ''ReadData'' necesite. Recuerde, su envío y recepción son independientes incluso en el nivel de hardware, por lo que no debe introducir sincronización de bloqueo u otra en este nivel.
3) Un conjunto de hilos Socket IO, que ciegamente procesan datos que se leen o se escribirán en un socket.
4) CALLBACK DE PROTOCOLO: un objeto de devolución de llamada al que los subprocesos tienen punteros inteligentes. Maneja cualquier capa de PROTOCOLO, como analizar el blob de datos en una solicitud HTTP real, que se encuentra en la parte superior de la conexión de socket básica. Recuerde, un socket es solo un conducto de datos entre las computadoras y los datos que se envían a menudo llegarán como una serie de fragmentos: los paquetes. En protocolos como UDP, los paquetes no están en orden. Los ''ReadData'' y ''WriteData'' de bajo nivel realizarán una devolución de llamada desde sus subprocesos hasta aquí, porque es donde realmente comienza el procesamiento de datos con conciencia de contenido.
5) Cualquier devolución de llamada que necesite el manejador de protocolo. Para HTTP, empaqueta los buffers de solicitud sin procesar en objetos agradables que transfiere a un servlet real, que debe devolver un buen objeto de respuesta que se puede serializar en una respuesta conforme a especificaciones HTTP.
Observe el patrón básico: tiene que hacer que todo el sistema sea fundamentalmente asincrónico (una "cebolla de devoluciones de llamada") si desea aprovechar al máximo las tomas IO bidireccionales y asíncronas. La única forma de leer y escribir simultáneamente en el socket es con hilos, por lo que aún podría sincronizar entre un hilo "escritor" y "lector", pero solo lo haría si el protocolo u otras consideraciones forzaran mi mano. La buena noticia es que puede obtener un gran rendimiento con sockets que utilizan un procesamiento altamente asincrónico, lo malo es que construir un sistema de este tipo de manera robusta es un esfuerzo serio.
No tienes que preocuparte por eso. Una lectura de hilo y una escritura de hilo funcionarán como esperabas. Los enchufes son full dúplex, por lo que puede leer mientras escribe y viceversa. Tendría que preocuparse si tuviera varios escritores, pero este no es el caso.