Количество параллельных сокетов / TCP-соединений, открываемых для оптимального использования приложением в C ++ - PullRequest
0 голосов
/ 04 января 2019

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

В настоящее время между любыми 2 одноранговыми узлами (скажем, A и B) приложение открывает два типа соединений - одно, где A является сервером, а B является клиентом, и наоборот. Возможно, это было сделано для того, чтобы, если A нужно было одновременно передавать данные в B и наоборот, все это может закончиться быстрее, чем просто иметь один тип соединения от A до B. Для каждого типа соединения (скажем, где A - сервер, а B - клиент), затем приложение открывает 3 TCP-соединения (используя C-сокеты). Тем не менее, способ, которым он в настоящее время закодирован, заканчивается только использованием одного из этих трех соединений.

Увидев это, я начал задаваться вопросом, что для оптимального использования N открытых соединений, возможно, можно использовать циклический перебор или некоторую политику, чтобы разбивать данные на куски и передавать одновременно. Однако вопрос о том, сколько параллельных TCP-соединений должно быть открыто и какую политику использовать между этими соединениями, мне не ясен. От каких факторов зависит и этот ответ? Например, если у меня открыто 1000 соединений TCP, какой вред? (игнорирование системных ограничений, таких как нехватка портов и т. д.)

Если кто-то может пролить свет на то, как современные приложения используют множественные параллельные TCP-соединения для обеспечения максимальной производительности, это было бы замечательно. Быстрый поиск в Google приводит меня к нескольким исследовательским работам, но мне также интересно узнать, как, например, веб-браузеры решают эту проблему.

Спасибо!


ОБНОВЛЕНИЕ: поговорив с несколькими людьми с большим знанием TCP, я пришел к более ясной картине. Во-первых, моя предпосылка о том, что открытие двух типов соединений между A и B (один, где A является клиентом, а B-сервером и наоборот) поможет увеличить пропускную способность, кажется неправильной. Открытие одного типа TCP-соединения между A и B должно быть достаточным. Это зависит от того, могут ли датаграммы перемещаться из А в В и наоборот одновременно. Я нашел эту ссылку полезной: Является ли TCP двунаправленным или дуплексным? .

Кроме того, чтобы использовать всю доступную мне пропускную способность, лучше открыть несколько соединений TCP. Я нашел эту очень актуальную ссылку: TCP, можно ли достичь более высокой скорости передачи при нескольких подключениях?

Но вопрос о том, сколько таких связей должно быть открыто, все еще остается. Было бы здорово, если бы кто-то мог ответить на этот вопрос.

Ответы [ 2 ]

0 голосов
/ 06 января 2019

При передаче данных между двумя хостами вряд ли будет какое-либо существенное преимущество в пропускной способности, которое будет получено при использовании более одного сокета TCP. При правильном программировании одно TCP-соединение может насыщать полосу пропускания канала в обоих направлениях одновременно (т. Е. Оно может выполнять полнодуплексный / двусторонний обмен на скорости линии). Разделение данных по нескольким TCP-соединениям просто добавляет издержки; в лучшем случае каждое из N соединений будет передавать со скоростью 1 / N скорость одного соединения (и в реальной жизни меньше, чем это из-за дополнительных заголовков пакетов, конкуренции за пропускную способность и т. д.).

Существует одно потенциальное (незначительное) преимущество, которое может быть реализовано при использовании нескольких потоков TCP, однако - это преимущество наблюдается только в случае, когда данные, передаваемые в потоке A, логически не зависят от данных, передаваемых в потоке B. Если это так (т. Е. Если получатель может немедленно использовать данные в потоке A, не дожидаясь, пока данные в потоке B поступят первыми), то наличие нескольких потоков может сделать передачу данных несколько более устойчивой к пакетам -dropouts.

Например, если поток A отбрасывает пакет, это приведет к тому, что поток A должен будет сделать кратковременную паузу, пока он повторно передает отброшенный пакет, но в то же время данные потока B могут продолжать течь без прерывания, поскольку поток B работает независимо из потока A. (Если бы A-данные и B-данные отправлялись по одному и тому же потоку TCP, OTOH, B-данные были бы вынуждены ждать повторной передачи потерянного A-пакета, так как строгий FIFO- порядок всегда применяется в потоке TCP).

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

0 голосов
/ 04 января 2019

Вы не указали ОС, поэтому я предполагаю, что речь идет о Linux. Я думаю, что вам нужно провести некоторое исследование о неблокирующем IO, например, epoll или asio. В настоящее время это наиболее эффективный и масштабируемый способ работы с несколькими подключениями одновременно.

Вы можете начать здесь , например.

Некоторый анализ производительности можно найти здесь или здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...