Дизайн большого объема TCP-клиента - PullRequest
3 голосов
/ 01 октября 2008

У меня есть .NET TCP-клиент, который отправляет большие объемы сообщений на (.NET async) TCP-сервер.

Мне нужно продолжать отправлять сообщения на сервер, но у меня заканчиваются порты на клиенте из-за TIME_WAIT.

Как программа может непрерывно и надежно отправлять сообщения, не используя все доступные порты?

Есть ли способ для повторного использования одного и того же сокета. Я посмотрел на Disconnect () и флаг сокета REUSEADDRESS, но не могу найти хороших примеров их использования. Фактически большинство источников говорят, что не следует использовать Disconnect, так как он используется для более низкого уровня (т. Е. Он только повторяет ручку сокета).

Я думаю, что мне нужно переключиться на UDP или, возможно, есть метод, использующий C ++ и IOCP?

Ответы [ 6 ]

5 голосов
/ 01 октября 2008

Вы можете оставить сокет открытым, если ваш сервер и клиент знают о формате данных. Вы закрываете сокет, чтобы сервер мог «увидеть», что клиент «готов».

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

Вы можете найти какой-нибудь токен в конце сообщения, вы можете передать длину сообщения, прочитать остальное в зависимости от размера и т. Д. Различные способы сделать это.

Но нет причин постоянно открывать и закрывать соединения с сервером - вот что вас здесь убивает.

1 голос
/ 01 октября 2008

TCP очень старается предотвратить перегрузку в сети. Все новые TCP-подключения начинаются в состоянии «медленного запуска», когда они отправляют только один пакет и ожидают подтверждения от другого конца. Если ACK получен, TCP отправит два пакета, затем четыре и т. Д., Пока не достигнет максимального размера окна.

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

Для этого вам нужно заставить сервер обрабатывать более одного сообщения в соединении (что означает поиск способа разграничить каждое сообщение). Если ваш сервер поддерживает HTTP-кодирование любого рода, это будет работать; Обязательно изучите любой аргумент или конфигурацию, относящиеся к «постоянным» соединениям или HTTP 1.1, потому что именно так HTTP отправляет несколько запросов по одному TCP-соединению.

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

1 голос
/ 01 октября 2008

Может ли ваш клиент оставить тот же сокет открытым и отправлять сообщения в цикле?

open socket connection

while(running)
    send messages over socket

close socket connection
0 голосов
/ 01 октября 2008

Основная идея написания TCP-серверов (на любом языке) - открыть один порт для прослушивания соединений, а затем создать новые потоки или процессы для обработки новых запросов на соединение.

open a server socket // this uses the port the clients know about

while(running)
    client_socket = server_socket.listen
    fork(new handler_object(client_socket))

Вот хороший пример на C # .

0 голосов
/ 01 октября 2008

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

Некоторый быстрый поиск в Google нашел эту документацию MSDN по созданию службы очереди сообщений с C # .

0 голосов
/ 01 октября 2008

При таком кодировании это не работает.

Сервер получает только первое сообщение.

Когда я открываю и закрываю сокет, сервер работает, но у меня заканчиваются клиентские порты.

Полагаю, именно дизайн моего сервера заставляет меня так кодировать клиента.

Так как же кодировать асинхронный сервер, используя .NET. Я следовал за примерами MSDN и многочисленными примерами онлайн.

...