Как многопоточный сервер продолжает прослушивать сообщения для получения дополнительных входящих соединений? - PullRequest
4 голосов
/ 18 января 2012

Я изучаю урок Sun по Java. Я на уроке о розетках. Для простого многопоточного сервера есть следующий код:

import java.net.*;
import java.io.*;

public class KKMultiServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
        boolean listening = true;

        try {
            serverSocket = new ServerSocket(4444);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 4444.");
            System.exit(-1);
        }

        while (listening)
        new KKMultiServerThread(serverSocket.accept()).start();

        serverSocket.close();
    }   
}

Говорят, что сервер "продолжает прослушивать больше входящих соединений". Я просто не понимаю, как это возможно; строка serverSocket.accept() создает новый (клиентский) объект Socket, который в соответствии с руководством "привязан к тому же локальному порту и имеет свой ...". Ну, как это возможно, что сервер взаимодействует с клиентом и прослушивает больше входящих соединений на том же порту? Насколько я знаю, если порт используется для какого-то соединения, он блокируется и не может использоваться для других целей.

Так что я тут не так делаю?

Ответы [ 5 ]

2 голосов
/ 18 января 2012

Ну, сокет не один-к-одному на основе порта, он уникален для кортежа (адрес, порт).Соединение - пара локальных и удаленных сокетов, участвующих в обмене данными - используется для демультиплексирования входящих данных из порта в правильный сокет, позволяя использовать несколько сокетов на одном порту. См. Википедию .Другими словами, отношение сокетов к портам равно N-1

.
1 голос
/ 21 июня 2012

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

[...] TCP демультиплексирует входящие сегменты, используя все четыре значения, которые включают локальные и внешние адреса: IP-адрес назначения, номер порта назначения, IP-адрес источника и номер порта источника. TCP не может определить, какой процесс получает входящий сегмент, глядя только на порт назначения. Кроме того, единственная из [различных] конечных точек в [заданном номере порта], которая будет принимать входящие запросы на соединение, - это та, которая находится в состоянии прослушивания. (p255, Иллюстрированный том TCP-IP, 1 , У. Ричард Стивенс)

Последнее предложение в приведенной выше цитате является ключом к пониманию.

Интересно, что сокет на самом деле не определяется комбинацией IP-адреса и порта. Это уникально только в контексте, где контекстом является либо конкретное соединение, либо состояние прослушивания. Только один сокет слушателя может быть привязан к определенной комбинации IP / порта.

1 голос
/ 18 января 2012

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

клиенты, пытающиеся подключиться к серверу, обычно получают порт, назначенный операционной системой, который в настоящее время не используется

0 голосов
/ 10 июля 2013

Короткий и приятный ответ: порт заблокирован для ДРУГИХ программ и процессов. Только программа, которая открыла порт, теперь может прослушивать его. НО он может прослушивать множество разных клиентов на одном и том же порту.

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

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

0 голосов
/ 18 января 2012

На основании этой ссылки

Метод accept ожидает, пока клиент запустится, и запросит соединение на хосте и порте этого сервера (в этом примере сервер работает на гипотетической машине taranis на порту 4444). Когда соединение запрашивается и успешно устанавливается, метод accept возвращает новый объект Socket, который связан с тем же локальным портом, и его удаленный адрес и удаленный порт установлены на том же клиенте. Сервер может связываться с клиентом через этот новый Сокет и продолжайте прослушивать запросы клиентских подключений на исходном ServerSocket. Эта конкретная версия программы не прослушивает больше запросов клиентских подключений.

Вот SO-обсуждение, которое может прояснить путаницу в отношении того, как один порт обрабатывает множественные клиентские вызовы Port and Socket SO-обсуждение .

Проще говоря, большинство веб-серверов прослушивают порт 8080, и несколько клиентов получат доступ к одному и тому же порту для доступа к вашему веб-сайту.

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