Быстро кросс-платформенная коммуникация процесса Интера в C++

Я ищу способ заставить две программы эффективно передавать большой объем данных друг другу, который должен работать над Linux и Windows в C++. Контекст здесь является сетевой программой P2P, которая действует как узел в сети и работает непрерывно, и другие приложения (который мог быть играми следовательно потребность в быстром решении), будет использовать это для общения с другими узлами в сети. Если бы существует лучшее решение для этого, мне было бы интересно.

20
задан Stephen Cross 7 February 2010 в 22:00
поделиться

6 ответов

boost :: asio - это кроссплатформенная библиотека, обрабатывающая асинхронный io через сокеты. Вы можете комбинировать это с использованием, например, буферов протокола Google для ваших фактических сообщений.

Boost также предоставляет вам boost :: interprocess для межпроцессного взаимодействия на одной и той же машине, но asio позволяет вам осуществлять обмен данными асинхронно, и вы можете легко иметь одни и те же обработчики как для локальных, так и для удаленных соединений.

15
ответ дан 30 November 2019 в 00:51
поделиться

Я использовал ICE от ZeroC ( www.zeroc.com), и это было фантастически. Супер проста в использовании, и она не только кроссплатформенная, но и имеет поддержку многих языков (питон, java и т.д.), и даже встроенную версию библиотеки.

6
ответ дан 30 November 2019 в 00:51
поделиться

Я настоятельно рекомендую Протоколные буферы поверх сокетов TCP или UDP.

1
ответ дан 30 November 2019 в 00:51
поделиться

Строка подключения мне кажется правильной. Вы уверены, что поставщик SQLite ADO.NET правильно установлен на сервере? Откройте файл machine.config и проверьте, есть ли запись для System.Data.SQLite в разделе DbProvireFactories

Ссылка на хороший ресурс о том, как создавать строки EF-соединений, также была бы очень полезна!

В основном необходимо указать: - метаданные модели (части с "res ://"...) - поставщик хранилища ("System.Data.SQLite" в вашем случае) - строка соединения хранилища, которая варьируется в зависимости от того, какой поставщик используется

Самый простой способ динамического построения строки соединения - использовать класс EntityConniceStringBuilder вместе с построителем строк соединения поставщика хранилища.

-121--4746323-

Возможно, вы можете сделать модели Джанго полиморфными, используя подход, описанный здесь . Этот код находится на ранних стадиях разработки, я считаю, но стоит изучить.

-121--1541274-

В то время как другие ответы охватывают часть проблемы (библиотеки сокетов), они не говорят вам о проблеме NAT. Вместо того, чтобы иметь пользователей с их маршрутизаторами, лучше использовать некоторые методы, которые должны помочь вам через смутно разумный маршрутизатор без дополнительной конфигурации. Вы должны использовать все это, чтобы получить лучшую совместимость.

Во-первых, библиотека ICE здесь - это метод обхода NAT, который работает с серверами STUN и/или TURN в сети. Возможно, вам придется предоставить некоторую инфраструктуру, чтобы это работало, хотя есть некоторые общедоступные серверы STUN.

Во-вторых, используйте UPnP и NAT-PMP. Например, одна библиотека здесь .

В-третьих, используйте IPv6. Teredo, который является одним из способов запуска IPv6 над IPv4, часто работает, когда никто из вышеперечисленных не делает, и кто знает, что ваши пользователи могут работать IPv6 какими-то другими способами. Очень мало кода для реализации этого, и все более важным. Я нахожу около половины данных Bittorrent поступает через IPv6, например.

0
ответ дан 30 November 2019 в 00:51
поделиться

Что ж, если мы можем предположить, что два процесса работают на одной машине, то самый быстрый способ для них передавать большие объемы данных туда и обратно - это хранить данные в общей области памяти; при такой настройке данные вообще никогда не копируются, поскольку оба процесса могут обращаться к ним напрямую. (Если вы хотите пойти еще дальше, вы можете объединить две программы в одну программу, при этом каждый предыдущий «процесс» теперь будет работать как поток внутри одного и того же пространства процессов. В этом случае они будут автоматически разделять 100% своей памяти. друг с другом)

Конечно, просто наличия общей области памяти в большинстве случаев недостаточно: вам также понадобится какой-то механизм синхронизации, чтобы процессы могли безопасно читать и обновлять общие данные, не спотыкаясь о каждом Другие. Я бы сделал это, создав две двусторонние очереди в области общей памяти (по одной для каждого процесса для отправки). Либо используйте класс FIFO-очереди без блокировки, либо дайте каждой двусторонней очереди семафор / мьютекс, который вы можете использовать для сериализации, вставляя элементы данных в очередь и выталкивая элементы данных из очереди. (Обратите внимание, что элементы данных, которые вы помещаете в очереди, будут только указателями на фактические буферы данных, а не сами данные ... в противном случае вы вернетесь к копированию больших объемов данных вокруг, чего вы хотите избежать . Рекомендуется использовать shared_ptrs вместо простых указателей C, чтобы «старые» данные автоматически освобождались, когда процесс получения завершит их использование).Когда у вас есть это, единственное, что вам нужно, это способ для процесса A уведомить процесс B, когда он только что поместил элемент в очередь для получения B (и наоборот) ... Я обычно делаю это запись байта в канал, в котором другой процесс использует select (), чтобы заставить другой процесс проснуться и проверить свою очередь, но есть и другие способы сделать это.

3
ответ дан 30 November 2019 в 00:51
поделиться

Это сложная проблема.

Узким местом является Интернет и то, что ваши клиенты могут подключаться к NAT.

Если вы не говорите об Интернете или если у вас явно нет клиентов, стоящих за злыми NAT операторского уровня, вам нужно сказать.

Потому что все сводится к следующему: использовать TCP. Успокойся.

1
ответ дан 30 November 2019 в 00:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: