2014-06-30 3 views
0

Я пишу клиент-серверное приложение (TCP-протокол) на C++.
У меня есть возможность, когда клиент может получать данные с нескольких серверов.
Чтобы решить эту проблему, я создал список соединений сокетов.Оптимизированный процесс приема пакетов данных при большой нагрузке на сеть

В цикле, на каждую розетке, я выполняю следующие действия:

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

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

Для обработки этого сценария одним из решений может быть предоставление выделенного буфера для каждого соединения.

Можно ли предложить более оптимизированное/лучшее решение, чтобы избежать создания выделенного буфера для каждого соединения?

+0

Взгляните на Boost Asio http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio.html, чтобы вам не пришлось изобретать колесо. В общем смысле, хотя, если вам нужно удержать экземпляры частичных данных, для этого вам нужен буфер. Также обратите внимание, что сетевой стек будет хранить данные TCP для вас, поэтому в зависимости от ваших точных требований, которые могут быть достаточно хорошими. –

+1

Проблема «не получения полной телеграммы» не уникальна для тяжелых нагрузок. У вас будет эта проблема и при легких нагрузках. Потоки сокетов TCP все время получают частичные данные - это характер TCP (через сегментацию, фрагментацию, отрыжки в сети и т. Д.).В любом случае, вы всегда будете хотеть зацикливаться на каждом сокете, пока не получите полное сообщение. – selbie

+0

@selbie: отличная точка, и одинаково: если вы отправляете два сообщения, они могут быть получены одним вызовом 'recv' или' read'. В конечном счете, TCP является протоколом * байтового потока * с контролем потока, и вы должны быть готовы к блокировке и/или частичным передачам и частичным/объединенным приемам. –

ответ

0

Я думаю, что если вы хотите обработать все сообщение/телеграмму только тогда, когда у вас есть все в памяти сразу, то единственный выделенный буфер приема для каждого TCP-соединения будет единственным способом. Если вы не очень ограничены в объеме оперативной памяти, доступной вам, или входящие сообщения очень велики, это не должно быть проблемой. (если это проблема, рассмотрите способы уменьшения количества сообщений, например, разбив каждое сообщение на ряд небольших сообщений, которые могут быть обработаны последовательно)

3

Если вы серьезно относитесь к этому, используйте поток для каждого сокета, каждый со своим собственным буфером, возможно, тоже обрабатывая обработку или передавая ее в поток обработки, зависящий от конкретного соединения, но вы также можете отправить все входящие данные в одну «рабочую» очередь, если это необходимо сделать по какой-то причине.

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

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