tuberias - Comunicación Interprocesos Rápidos de Plataforma Cruzada en C++
tuberias bidireccionales en c (6)
Estoy buscando una manera de lograr que dos programas se transmitan de manera eficiente una gran cantidad de datos entre sí, que necesita funcionar en Linux y Windows, en C ++. El contexto aquí es un programa de red P2P que actúa como un nodo en la red y se ejecuta continuamente, y otras aplicaciones (que podrían ser juegos, por lo tanto, la necesidad de una solución rápida) usarán esto para comunicarse con otros nodos en la red. Si hubiera una mejor solución para esto, estaría interesado.
Bueno, si podemos asumir que los dos procesos se ejecutan en la misma máquina, entonces la forma más rápida de transferir grandes cantidades de datos es mantener los datos dentro de una región de memoria compartida; Con esa configuración, los datos nunca se copian, ya que ambos procesos pueden acceder a ellos directamente. (Si quisiera ir aún más lejos, podría combinar los dos programas en un solo programa, con cada "proceso" anterior ahora ejecutándose como un hilo dentro del mismo espacio de proceso. En ese caso, compartirían automáticamente el 100% de su memoria. juntos)
Por supuesto, solo tener un área de memoria compartida no es suficiente en la mayoría de los casos: también necesitaría algún tipo de mecanismo de sincronización para que los procesos puedan leer y actualizar los datos compartidos de forma segura, sin tropezar unos con otros. La forma en que lo haría sería crear dos colas de doble extremo en la región de memoria compartida (una para cada proceso con el que enviar). Utilice una clase de cola FIFO sin bloqueo, o asigne a cada cola de doble cola un semáforo / mutex que pueda usar para serializar la inserción de elementos de datos en la cola y la extracción de elementos de datos de la cola. (Tenga en cuenta que los elementos de datos que pondría en las colas solo serían punteros a los buffers de datos reales, no a los datos en sí mismos ... de lo contrario, volvería a copiar grandes cantidades de datos, lo que quiere evitar . Es una buena idea usar shared_ptrs en lugar de punteros C simples, para que los datos "antiguos" se liberen automáticamente cuando el proceso de recepción se realiza con ellos. Una vez que tenga eso, lo único que necesitaría es una forma para que el proceso A notifique al proceso B cuando acaba de poner un elemento en la cola para que B lo reciba (y viceversa) ... Por lo general, lo hago escribir un byte en una tubería en la que se selecciona () el otro proceso para hacer que el otro proceso se active y verifique su cola, pero también hay otras formas de hacerlo.
Entonces, mientras que las otras respuestas cubren parte del problema (bibliotecas de socket), no le informan sobre el problema de NAT. En lugar de hacer que sus usuarios jueguen con sus enrutadores, es mejor usar algunas técnicas que lo ayuden a atravesar un enrutador vagamente sano sin ninguna configuración adicional. Necesitas usar todo esto para obtener la mejor compatibilidad.
Primero, la biblioteca ICE aquí es una técnica de NAT transversal que funciona con los servidores STUN y / o TURN en la red. Es posible que tenga que proporcionar alguna infraestructura para que esto funcione, aunque hay algunos servidores STUN públicos.
En segundo lugar, utilice tanto UPnP como NAT-PMP. Una biblioteca here , por ejemplo.
En tercer lugar, utilice IPv6. Teredo, que es una forma de ejecutar IPv6 sobre IPv4, a menudo funciona cuando ninguno de los anteriores lo hace, y quién sabe, sus usuarios pueden tener IPv6 funcionando por algún otro medio. Muy poco código para implementar esto, y cada vez más importante. Encuentro que aproximadamente la mitad de los datos de Bittorrent llegan a través de IPv6, por ejemplo.
Es este un problema difícil.
El cuello de botella es Internet y que sus clientes pueden estar en NAT.
Si no está hablando por Internet, o si explícitamente no tiene clientes detrás de NAT maliciosos de nivel de operador, debe decir.
Porque se reduce a: usar TCP. Chúpalo.
He estado usando ICE by ZeroC ( www.zeroc.com ), y ha sido fantástico. Súper fácil de usar, y no solo es multiplataforma, sino que también es compatible con muchos idiomas (python, java, etc.) e incluso una versión incorporada de la biblioteca.
Recomiendo encarecidamente Protocol Buffers encima de sockets TCP o UDP.
boost::asio es una biblioteca multiplataforma que maneja io asíncrono sobre sockets. Puede combinar esto con, por ejemplo, usar Google Protocol Buffers para sus mensajes reales.
Boost también le brinda boost::interprocess para la comunicación entre procesos en la misma máquina, pero asio le permite realizar su comunicación de forma asíncrona y puede tener fácilmente los mismos controladores para las conexiones locales y remotas.