2010-02-07 2 views
18

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

+5

Я немного не уверен в вопросе ... вы спрашиваете о передаче данных между двумя процессами на одном хосте или двух процессах, которые (или могут быть) запущены на разных хостах? –

+0

Если вы ищете лучшее решение, что вы делаете сейчас? – ergosys

+0

@Jeremy: Извините, я не был достаточно ясен. Эти два процесса находятся на одной машине. –

ответ

15

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

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

+1

yep, выигрышная комбинация –

+0

Хорошо, похоже, что boost - это способ пойти с этим ... Я уже использую его для boost :: signal, и я, вероятно, буду использовать его для boost :: asio –

+0

С буферами протокола Google , вы можете выбрать [много доступных реализаций RPC] (http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns). –

2

Это трудная проблема.

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

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

Потому что это сводится к: использованию TCP. Поднимите его.

+0

Два процесса находятся на одной машине, но один из них общается с Интернетом. Другой процесс должен связываться с этим, чтобы отправлять данные в сети P2P. –

+0

ага, и я думал, что вопрос о том, как создать сеть P2P. Я даже не начал работу на перфорационных и ретрансляционных серверах и тому подобное. – Will

1

Я бы настоятельно рекомендовал Protocol Buffers поверх сокетов TCP или UDP.

+2

Хотя UDP может быть хорош в определенных обстоятельствах, TCP - это путь, если вы хотите, чтобы данные были там в одной части, а латентность - не самый важный компонент. – Xorlev

6

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

+1

ICE либо требует, чтобы вы опубликовали свою программу под лицензией GPL или приобрели коммерческую лицензию, которая может или не может представлять проблему для OP. – villintehaspam

+1

Сама программа будет лицензирована под GPL, так что это не проблема –

+0

ZeroC использует буферы протокола Google. –

1

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

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

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

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

3

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

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

Смежные вопросы