Метод 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
), но вы можете его добавить.