Оптимизированный процесс получения пакетов данных во время большой нагрузки сети
Я пишу клиент-серверное приложение (протокол TCP) на C++.
У меня есть возможность, где клиент может получать данные с нескольких серверов.
Для решения этой проблемы я создал список соединений с сокетами.
В цикле на каждом сокете я выполняю следующее:
- попробуйте получить данные об этом на сокете
- положить это в буфер
- данные буфера обработки
- очистить буфер
- выполнить те же шаги для следующего сокета
Теперь в моем дизайне изначально я создал общий буфер для всех соединений. Но я полагаю, что в случае большой нагрузки в сети может случиться так, что полученная телеграмма не будет полной телеграммой, она может быть частью телеграммы. поэтому, чтобы завершить телеграмму, мне придется ждать следующей итерации для того же сокета, и даже сбор / идентификация телеграмм будет сложным процессом.
Для обработки этого сценария одним из решений может быть предоставление выделенного буфера для каждого соединения.
Кто-нибудь может предложить более оптимизированное / лучшее решение, чтобы избежать создания выделенного буфера для каждого соединения?
2 ответа
Если вы серьезно относитесь к этому, вы должны использовать поток на сокет, каждый со своим собственным буфером, возможно, выполняющий обработку тоже или передающий его в поток обработки для конкретного соединения, но вы также можете отправить все входящие данные в один "рабочая" очередь, если по какой-то причине это нужно делать последовательно.
Если вы должны использовать один поток, то вы должны использовать буфер для каждого соединения. TCP реализует своего рода управление потоком, которое означает, что отправляющей стороне может быть даже запрещено отправлять больше сообщения, пока принимающая сторона не израсходует достаточно. Если вас беспокоит использование памяти, вы можете удалить специфичные для соединения буферы, которые были полностью обработаны, и воссоздать их только при обнаружении неполного сообщения, но обычно страницы, к которым недавно не обращались, заменяются в ситуациях с нехваткой памяти таким образом, в сохранении памяти будет мало вреда - пока ваше (виртуальное) адресное пространство достаточно: время и фрагментация, связанные с повторяющимися динамическими распределениями памяти и освобождениями, могут быть хуже, чем пиковое использование памяти.
Я думаю, что если вы хотите обрабатывать все сообщение / телеграмму только тогда, когда у вас есть все это в памяти сразу, то выделенный буфер приема для каждого соединения TCP будет единственным способом. Если вы не очень ограничены в объеме оперативной памяти, или входящие сообщения очень большие, это не должно быть проблемой. (если это проблема, рассмотрите способы сделать сообщения меньше; например, разбив каждое сообщение на серию меньших сообщений, которые можно обрабатывать последовательно)