С# Sockets vs Pipes

В настоящее время я работаю над многозадачным настольным приложением в Windows. Это приложение будет сжатым приложением, которое будет развернуто на клиентских компьютерах по всему миру. Хотя мы можем иметь широкие спецификации для машин - например, Windows XP SP3 с .Net 4.0 CF, мы не будем контролировать их, и мы не можем быть слишком конкретными в их конфигурации - например. мы не можем указать, что на машине должен быть графический процессор с поддержкой cuda 1.4 и т.д.

Некоторые из этих процессов управляются (.Net 4.0), а другие неуправляемы (С++ Win32). Процессам необходимо обмениваться данными. Параметры, которые я оценил до настоящего времени,

  • Разъемы Tcp
  • Именованные каналы

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

Однако, моя главная проблема заключается в следующем: если мы будем использовать сокеты Tcp, мы, вероятно, столкнемся с проблемами с брандмауэрами? Кто-нибудь еще развернул настольные приложения/программы, использующие TCP для IPC и возникшие проблемы? Если да - какой?

Я знаю, что это довольно открытый вопрос, и я буду рад перефразировать. Но я действительно хотел бы знать, какие потенциальные проблемы мы можем столкнуться.

edit: Чтобы выпустить немного больше света, мы переносим только несколько POD, ints, float и strings. Мы создали слой абстракции, который предлагает 2 парадигмы - запрос/ответ и подписку. Транспортный уровень был абстрагирован, и в настоящее время мы имеем две реализации: на основе протокола и TCP.

Ответ 1

Производительность труб часто лучше в быстрой локальной сети, но TCP часто лучше работает в более медленных сетях или глобальных сетях. См. Ниже пункты msdn.

TPC также более настраивается. Что касается брандмауэров, они позволяют открывать/закрывать коммуникационные порты. Если это не вариант или проблема, другой вариант будет http (REST/json, веб-сервис, xml rpc и т.д.), Но не уверен, что служебные данные http приемлемы. Удостоверьтесь, что вы попробуете его с наборами данных реального мира (передача тривиальных данных в тесте делает накладные расходы кажутся необоснованными - часто это незначительное по сравнению с набором данных реального мира).

Некоторая информация из msdn:

В среде быстрой локальной сети (ЛВС) управление передачей Протоколы/Интернет-протокол (TCP/IP) Сокеты и именованные каналы сопоставимы с точки зрения производительности. Однако производительность разница между сокетами TCP/IP и именными каналами очевидно, с более медленными сетями, например, в глобальных сетях (WAN) или коммутируемых сетей. Это связано с тем, механизмы межпроцессного взаимодействия (IPC) взаимодействуют между одноранговыми узлами.

Для именованных каналов сетевая связь обычно больше интерактивный. Одноранговый узел не отправляет данные, пока другой его не попросит используя команду чтения. Обычно чтение сети включает в себя ряд peek named pipe messages, прежде чем он начнет считывать данные. Они могут быть очень дорогостоящим в медленной сети и вызывать чрезмерный сетевой трафик, который, в свою очередь, влияет на других сетевых клиентов.

Также важно уточнить, если вы говорите о локальных трубах или сетевых труб. Если серверное приложение выполняется локально на компьютер с экземпляром Microsoft® SQL Server ™ 2000, локальный Протокол Named Pipes является опцией. Локальные именованные каналы работают в ядре и очень быстро.

Для сокетов TCP/IP передача данных более упорядочена и имеет меньше накладных расходов. Передача данных также может использовать преимущества TCP/IP Механизмы повышения производительности сокетов, такие как оконные, отложенные подтверждения и т.д., что может быть очень полезным при медленном сеть. В зависимости от типа приложений такая производительность различия могут быть значительными.

Сокеты TCP/IP также поддерживают очередь хранения, которая может обеспечить ограниченный эффект сглаживания по сравнению с именованными трубами, которые могут привести к трубе когда вы пытаетесь подключиться к SQL Server.

В общем случае сокеты предпочтительнее в медленной локальной сети, WAN или dial-up сети, тогда как именованные каналы могут быть лучшим выбором при скорости сети это не проблема, поскольку она предлагает больше функциональности, простоты использования и параметры конфигурации.

Дополнительные сведения о TCP/IP см. в Microsoft Windows NT® документация.

Ответ 2

Если вам нужно выдавать идентификаторы безопасности клиента именованного канала, там действительно только один вариант:) И названные каналы также имеют более приятные имена (хотя DNS SRV-записи также могут предоставлять для портов TCP.)

В противном случае нет большой разницы. Оба обрабатывают данные как поток байтов, оставляя вас ответственными за поиск границ сообщений. У именованных каналов есть дополнительная возможность сохранять границы сообщений для вас, но будьте осторожны, вы должны создать канал в режиме сообщения и явно установить режим чтения.

Ответ 3

Если я правильно понимаю ваши требования, вам необходимо установить связь между процессами, запущенными на одном компьютере. Процессы, вероятно, запускают все в одном и том же контексте безопасности пользователя, который регистрируется в интерактивном режиме.

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

В рамках этого аспекта я бы предложил вам два других варианта, которые вы не включили в свой вопрос:

  • файлы с памятью использования (см. здесь и здесь)
  • использование COM-интерфейса

Оба способа могут быть хорошо реализованы как на .NET, так и на неуправляемом С++. Использование файлов с отображением памяти является лучшим способом с точки зрения производительности. Если вы создаете View, который не будет связан с каким-либо физическим файлом, вы будете иметь только общую память, которая может использоваться между процессами. Вы можете дополнительно использовать Mutex или Event для управления тем, что память не будет использоваться одновременно несколькими приложениями.

В самом простом сценарии вы даже можете использовать # pragma data_seg в С++ для размещения некоторых данных в именованном разделе DLL и использовать /SECTION (например, /SECTION:.MYSEC,RWS) для совместного использования данных. Вы можете использовать DLL во всех своих приложениях .NET и во всех неуправляемых приложениях С++ для доступа к общим данным. В способе вы получите простой способ доступа к общим данным.

Если вам нужен более сложный коммуникационный сценарий, лучшим вариантом может быть подход с COM-интерфейсом в С++/. NET. В случае, если я рекомендую вам статью, которая описывает шаг за шагом, как реализовать Первичную сборку Interop с интерфейсом COM только в .NET и использует ее в .NET и С++ COM для связи.