Метод accept Server (ServerSocket)

Кто знает, как выбирается порт, когда я использую метод accept класса ServerSocket? Можно ли определить диапазон для портов, из которых может выбрать метод? Могу ли я "брать" порты по порядку?

ServerSocket sSocket = new ServerSocket(5050);
Socket socket = sSocket.accept();

From the book

Ответ 1

Диаграмма неверна (и указана в неподтвержденных ошибках на сайте O'Reilly).

Клиент выбирает свой порт случайным образом (вам не нужно делать ничего особенного в Java) и подключается к серверу с любого порта, который вы указали. Используя инструмент командной строки netstat, вы можете это увидеть.

Во-первых, просто слушающий сокет сервера без клиентов:

[email protected]:~$ netstat -n -a
Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address     (state)
...
tcp46      0      0  *.5050                 *.*                 LISTEN
...

(есть много других записей, я только что удалил несвязанные)

Теперь с одним клиентом, подключающимся с локального хоста (127.0.0.1):

[email protected]:~$ netstat -n -a
Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address     (state)
...
tcp4       0      0  127.0.0.1.64895        127.0.0.1.5050      ESTABLISHED <- 1
tcp4       0      0  127.0.0.1.5050         127.0.0.1.64895     ESTABLISHED <- 2
tcp46      0      0  *.5050                 *.*                 LISTEN      <- 3
...

Поскольку клиент подключается с одной и той же машины, мы видим два установленных подключения - одно от клиента к серверу (1), другое от сервера к клиенту (2). Они имеют противоположные локальные и внешние адреса (поскольку они общаются друг с другом), и вы можете видеть, что сервер все еще использует порт 5050, в то время как исходный сокет сервера (3) продолжает прослушивать тот же порт.

(это вывод от Mac, но Windows/Linux также имеет netstat выдающий аналогичный вывод)

Ответ 2

Вы выбрали порт, когда вы сказали новый ServerSocket (5050). Все, что связано с использованием другого порта для принятого сокета, это 100% BS.

Ответ 3

TCP-соединение состоит из четырех частей:

  • Клиентский IP
  • Порт клиента
  • Сервер IP
  • Порт сервера

Может быть, например, несколько клиентов, подключенных к одному и тому же серверному порту, - пока клиенты не имеют один и тот же IP и тот же самый prt, это нормально. И для этой части операционная система заботится.

Так что вполне нормально слушать только один порт.

Ответ 4

ServerSocket определяет порт как часть конструктора. Если вы не укажете порт, сокет не связан (т.е. Невозможно получить доступ).

Чтобы получить порт соединительного разъема, используйте getPort(), а не getLocalPort(). Второй предоставит вам порт на вашем сервере.

Ответ 5

Вы можете передать 0 в качестве номера порта для создания сокета сервера на любом свободном порту или создать такой способ, чтобы создать серверный сокет для любого свободного порта в заданном диапазоне:

public java.net.ServerSocket createServerSocket(int rangeStart, int rangeEnd)
                            throws java.io.IOException {
  for(int port=rangeStart; port<=randeEnd; port++) {  
    try {
      return new ServerSocket(port);
    } catch(java.net.BindException be) {
      // debug/warning here
      continue;
    }
  }
  throw new java.io.IOException("Failed to create a server socket, all ports between " +
                                rangeStart + " - " + rangeEnd + " are already in use.");
}

Цикл не заботится о другом исключении (например, SecurityException), но вы можете его добавить.