Пассивные и активные розетки - PullRequest
9 голосов
/ 15 января 2011

Цитирование из этого руководства по сокетам :

Сокеты выпускаются в двух основных вариантах.Активный сокет подключен к удаленному активному сокету через открытое соединение для передачи данных ... Пассивный сокет не подключен, а ожидает входящее соединение, которое порождает новый активный сокет после установления соединения ...

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

Затем в руководстве объясняется, что после установления соединения активный сокет продолжает получать данные до тех пор, пока не останется байтов, а затем закрывает соединение.

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

Мой второй вопрос: кто определяет лимит одновременно работающих активных сокетов?

Ответы [ 3 ]

7 голосов
/ 15 января 2011

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

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

Это также зависит от таких факторов, как пропускная способность, передача данных для каждого клиента, память, тактовая частота и т. Д. Но неблокирование и блокировка могут существенно повлиять на число клиентов, которых вы можете принять. Вероятно, вы не можете иметь более 5-10 клиентов, блокирующих без сбоя вашего сервера ... но вы можете иметь тысячи, если не блокируете.

4 голосов
/ 16 июня 2015

Пожалуйста, не путайте фактические пакеты, отправленные реализацией TCP / IP по сети, и взаимодействие между вашей программой и библиотекой, реализующей TCP / IP.

Сокет - это просто абстракция, представленная вашей программеРеализация TCP / IP (библиотека или ядро ​​ОС).Вы можете визуализировать сокет как соединение с каналом (localIP: port-remoteIP: port).Ваша программа открывает сокет, передает данные через сокет и может закрыть сокет, если он больше не нужен для освобождения ресурсов.Это нормальный поток.Однако реализация TCP / IP может закрывать сокет по своим собственным уважительным причинам.Некоторые из этих причин: отключение кабеля доступа к сети, ошибки сетевой маршрутизации, отключение сервера и т. Д. Таким образом, ваша программа может обнаружить сокет tcp / ip закрытым, даже если он не закрыл его.

Теперь ваш первый вопрос: что мне делать, если моя программа отправляет небольшие сегменты данных с длинной паузой между ними.Ответ: зависит от того, сколько длится пауза и какая программа слушает вас на другой стороне.Большинство реализаций TCP / IP имеют представление о времени ожидания соединения, чтобы предоставить вам абстракции надежного соединения в реальных ненадежных сетях.Таким образом, если ваша программа сделает паузу дольше, чем время ожидания tcp / ip, вы обнаружите, что ваш сокет был закрыт библиотекой, и вам нужно будет снова открыть сокет.Это также может привести к тому, что вы возобновите связь снова, это зависит от программы, которая прослушивает вас на другой стороне канала соединения tcp / ip.

Существуют способы увеличения времени ожидания tcp / ip и его поддержания.Это может быть сделано как часть конфигурации сети, конфигурации программного обеспечения сервера на другом конце или если вы явно просите оставить сокет открытым, установив параметры KEEPALIVE в вызове библиотеки tcp / ip.Будет ли это все еще открыто или нет, зависит.Полная информация о том, как tcp / ip будет держать сокет открытым, не должна смущать вас, поскольку это не имеет никакого отношения к вашему коду.TCP / IP имеет множество настроек и различных тайм-аутов, чтобы обеспечить вашей программе иллюзию стабильного надежного соединения.Хорошая часть - все это скрыто от кода вашей программы, если вы не злоупотребляете им.Держите паузу менее нескольких секунд :) Один набор настроек времени ожидания может хорошо работать для небольших приложений в надежной локальной сети и не будет работать для приложений с высокой нагрузкой или через межконтинентальное соединение.Каждая конкретная ситуация имеет свое собственное решение, часто более одного.

В этом конкретном вопросе «отправлять небольшие данные каждые 20 минут» я бы посоветовал вам закрывать и открывать сокетное соединение для каждого сообщения.Время открытия одного меньше секунды и не должно влиять на ваше общение.Взамен вы получаете меньше сложности в вашем протоколе связи.Приемник всегда запускается заново при новом соединении через сокет, и обе системы могут пользоваться бесплатными ресурсами для связи tcp / ip в течение всех 20 минут, когда вам это не нужно.

0 голосов
/ 15 января 2011

Первый вопрос: Да, когда сокет закрыт, вы должны открыть его, чтобы возобновить связь.

Второй вопрос: Ты сделаешь. Если вы хотите, вы можете создать 64k подключений к вашему серверу и страдать от истощения портов (я не рекомендую этого). Как указано в ktm5124, все зависит от вашего приложения. Существует несколько различных способов сделать ваш сервер масштабируемым, включая использование асинхронного ввода-вывода и / или пула потоков для обработки клиентских запросов.

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