2011-01-14 4 views
8

Цитируя this socket tutorial:Пассивные и активные розетки

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

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

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

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

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

+1

Вы перефразируете эту статью и берете кусочки из разных частей статьи. Контексты разные. В последнем разделе автор объясняет свою программу. Сокеты не действуют по умолчанию, на самом деле, если вы забудете закрыть свой сокет, что-то может и произойдет. Сокет не закрывается автоматически при получении последнего байта. – SRM

+0

ОК, я думал, что это соглашение, и просто спросил, чего я здесь не хватает. Я новичок в концепциях, поэтому я хочу расспросить все, что мне трудно понять. – aslisabanci

+0

Нет проблем, я просто хотел убедиться, что вы понимаете, что вы должны явно закрыть сокет. Это может сэкономить вам несколько головных болей по линии, когда вы почесываете голову, пытаясь понять, почему сокет не закрылся :). – SRM

ответ

6

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

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

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

+0

Итак, постоянно ли отправляйте эти пакеты keepalive в течение 20 минут более дешевую операцию, чем повторное установление соединения каждый раз? Каковы были бы преимущества сохранения связи, кроме того, чтобы избежать накладных расходов на повторное подключение? – aslisabanci

+1

На самом деле, если у вас будет много клиентов, и каждый запрос будет быстрым (20 секунд, как вы сказали), тогда лучше всего использовать шаблон типа запроса/ответа. У вас есть только 64-килобайтные порты, что означает, что на IP-адрес могут быть приняты только 64-разрядные сокеты, прежде чем вы получите исчерпание порта, если эти сокеты не будут закрыты. Это действительно зависит от вашего приложения. Например, если вы пишете MMO, вам понадобятся постоянные соединения. Если вы пишете веб-сервер, хотя вам не понадобятся (и будут стараться избегать) постоянных подключений (если вы не используете HTML5, но это сложная история). – SRM

+2

С точки зрения клиента, простой keepalive для одного сервера - это не очень много работы. Вероятно, вы уже регулярно отправляете полдюжины keepalives, когда вы подключены к Интернету. С точки зрения сервера может быть полезно сохранить количество сокетов в списке сокетов как минимум, чтобы улучшить производительность ввода-вывода. Если между передачами данных осталось 20 минут, я каждый раз создавал новое соединение. Это незначительно для клиента, но не для сервера. – ktm5124

0

Первый вопрос: Да, как только розетка закрыта, вы должны выполнить команду «Открыть» для повторного инициирования связи.

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

+0

Пожалуйста, см. Ответ на вопрос http://stackoverflow.com/a/2332756/1418457 Возможно, вы неправильно поняли что-то о TCP – onmyway133

+0

Хорошо, если истощение порта TCP/IP является только клиентской стороной (как указано в лимите 64k на клиент на серверный порт), то почему существует проблема реального мира, связанная с исчерпанием портов на серверах? Вы все равно можете использовать все значения кортежа - возможно, мой номер 64k ошибочен, но существует ограничение на количество комбинаций, которые может содержать кортеж. Когда у вас заканчиваются комбинации, если вы повторно используете адрес, у вас не хватит адресов (на самом деле уникальный набор), чтобы назначить входящее соединение, и соединение будет отклонено. – SRM

3

Пожалуйста, не путайте фактические пакеты, отправленные реализацией 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 минут, когда вам это не нужно.

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