Блоки сокетов Java при подключении к серверу - PullRequest
6 голосов
/ 17 апреля 2011

Я пытаюсь подключиться к серверу с помощью сокета Java.Я пытаюсь подключиться с порта 80 на 90

int port;
Socket clientsocket;
String hostname = "www.google.com";

for(port = 80;port<=90; port++){
  try{
    clientsocket = new Socket(hostname,port);
    System.out.println("Connection at port " + port + "\t" + clientsocket.isConnected());
    clientsocket.close();
  }
  catch(Exception e){
    System.out.println(e.getMessage());
  }
}

Когда я пытаюсь подключиться к любому веб-сайту, например google.com или w3schools.com, моя программа зависает при вызове socket() для номеров портов, кроме 80.Поскольку эти сайты не обслуживают порты 81-90, они должны вызвать исключение, но вместо этого они блокируются.Для порта 80 работает нормально.Когда я пытаюсь подключиться к серверу apache, установленному на моей машине, он не блокируется ни для одного номера порта и выдает ошибку «Отказ в соединении», что является очевидным поведением.Так почему это происходит?Заранее спасибо.

1 Ответ

16 голосов
/ 17 апреля 2011

Когда я пытаюсь подключиться к любому веб-сайту, например google.com или w3schools.com, моя программа зависает при вызове socket () для номеров портов, кроме 80. Поскольку эти сайты не обслуживают порты 81-90, следуетвызвать исключение, но вместо этого оно блокируется.

Это почти наверняка не делает Java.

Когда вы вызываете конструктор Socket(String, int), JVM просит ОС попытаться установитьподключение к IP-адресу, соответствующему указанному имени, с использованием предоставленного номера порта.Предполагая, что мы говорим о TCP / IP, ОС отправляет сообщение TCP «SYN» и ожидает ответа:

  • Если ответом является «SYN-ACK»,это продолжает устанавливать соединение согласно протоколу;см. http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_establishment.

  • Если ответом является «RST» (сброс), соединение завершается неудачно, и это приводит к исключению «отказано в соединении» в Java.(Обычно это происходит, если «SYN» делает это с удаленным сервером, только для того, чтобы обнаружить, что нет приложения, «прослушивающего» порт, к которому вы пытались подключиться.)

  • Если ответ является ICMP-сообщением какого-либо вида (например, ICMP-адрес недоступен), это обычно приводит к немедленному сбою запроса на соединение и исключению Java.

  • Если естьНет ответа, ОС пытается снова, и снова, и снова.В зависимости от времени ожидания соединения Java по умолчанию (или явного времени ожидания) этот процесс может продолжаться в течение длительного времени.

Так что, скорее всего, происходит то, что что-то фильтрует 'SYN'сообщения на фанк-портах и ​​просто выбрасывая их.Это может быть локальное программное обеспечение брандмауэра на вашем ПК, программное обеспечение брандмауэра на вашем шлюзе или сеть вашего интернет-провайдера, или программное обеспечение в удаленной системе, с которой вы пытаетесь установить связь.Или это может происходить при возвращении сообщения «SYN-ACK».

В любом случае поведение блокировки / тайм-аута присуще сетям TCP / IP, и невозможно точно диагностировать ни в ОС, ни вУровни Java.Вам просто нужно скорректировать свои ожидания.(Или установите более короткий тайм-аут соединения ...)

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