Сеть Java "Соединение отказано: Соединиться" - PullRequest
10 голосов
/ 10 февраля 2011

Я пытался запустить простую программу тестирования сети без результатов.

Сервер:

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

public class ServerTest {
    public static void main(String[] args) {
    final int PORT_NUMBER = 44827;

    while(true) {
        try {
        //Listen on port
        ServerSocket serverSock = new ServerSocket(PORT_NUMBER);
        System.out.println("Listening...");

        //Get connection
        Socket clientSock = serverSock.accept();
        System.out.println("Connected client");

        //Get input
        BufferedReader br = new BufferedReader(new InputStreamReader(clientSock.getInputStream()));
        System.out.println(br.readLine());

        br.close();
        serverSock.close();
        clientSock.close();
        } catch(Exception e) {
        e.printStackTrace();
        }
    }
    }
}

Клиент:

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

public class ClientTest {
    public static void main(String[] args) throws IOException {
    final int PORT_NUMBER = 44827;
    final String HOSTNAME = "xx.xx.xx.xx";

    //Attempt to connect
    try {
        Socket sock = new Socket(HOSTNAME, PORT_NUMBER);
            PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
        //Output
        out.println("Test");
        out.flush();

        out.close();
        sock.close();
    } catch(Exception e) {
        e.printStackTrace();
    }
    }
}

Программаработает нормально, когда я использую 127.0.0.1 или мой внутренний IP-адрес для имени хоста.Но всякий раз, когда я переключаюсь на свой внешний IP-адрес, он выдает ошибку java.net.ConnectException: Connection refused: connect.

Я специально выбрал такой необычный порт, чтобы посмотреть, не в этом ли проблема, но не повезло.Я могу без проблем подключиться с помощью telnet, но когда я пытаюсь получить доступ к порту с помощью canyouseeme.org, он сообщает мне, что время соединения истекло.Я даже пытался отключить все брандмауэры и антивирусы, включая стандартные Windows и брандмауэр маршрутизатора, со всеми переадресованными портами и включенной DMZ, и он по-прежнему говорит, что время соединения истекло.Я использую Comcast в качестве своего провайдера, и сомневаюсь, что они блокируют такой случайный порт.

Когда я использую трассировщик пакетов, он показывает трафик TCP, когда мой компьютер отправляет SYN и получает RST / ACK, поэтому выглядитстандартный заблокированный порт, и никакой другой подозрительный пакетный трафик не происходил.

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

Ответы [ 5 ]

7 голосов
/ 16 июня 2013

Эта проблема возникает в следующих ситуациях:

  1. Клиент и сервер, либо оба, либо оба не находятся в сети.

  2. Сервер не работает.

  3. Сервер работает, но не прослушивает порт, клиент пытается подключиться.

  4. Брандмауэр не разрешен для комбинации хост-порт.

  5. Неправильная комбинация хост-порта.

  6. Неверный протокол в соединительной строке.

Как решить проблему:

  1. Сначала вы пингуете целевой сервер. Если это пингует правильно, тогда клиент и сервер находятся в сети.

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

2 голосов
/ 11 февраля 2011

Как бы то ни было, ваш код отлично работает в моей системе.

Мне неприятно это говорить, но это звучит как проблема с брандмауэром (которую я знаю, что вы уже трижды проверили) или Comcast проблема , которая более вероятна, чем вы думаете. Я бы проверил вашего провайдера .

0 голосов
/ 15 февраля 2016

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

Моим первым (не очень элегантным) решением было остановить клиента на некоторое время с помощью метода сна:

try {
   Thread.sleep(1000);
} 
catch (InterruptedException e) {
   e.printStackTrace();
}

Я использую этот код непосредственно перед подключением клиента, в вашем примере, перед Socket sock = new Socket(HOSTNAME, PORT_NUMBER);

Мое второе решение было основано на этом ответе. По сути, я создал метод в классе клиента, этот метод пытается подключиться к серверу и, если соединение не удается, он ждет две секунды, прежде чем повторить попытку. Это мой метод:

private Socket createClientSocket(String clientName, int port){

    boolean scanning = true;
    Socket socket = null;
    int numberOfTry = 0;

    while (scanning && numberOfTry < 10){
        numberOfTry++;
        try {
            socket = new Socket(clientName, port);
            scanning = false;
        } catch (IOException e) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }

    }
    return socket;
}

Как видите, этот метод пытается создать сокет десять раз, а затем возвращает нулевое значение для сокета, поэтому будьте внимательны и проверьте результат.

Ваш код должен стать:

Socket sock = createClientSocket(HOSTNAME, PORT_NUMBER);
if(null == sock){ //log error... }

Это решение помогло мне, надеюсь, оно поможет и вам. ; -)

0 голосов
/ 19 сентября 2011

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

Я также написал пост в блоге о переадресации портов, вы можете посмотреть :) http://happycoders.wordpress.com/2010/10/03/how-to-setup-a-web-server-by-yourself/

Но я все еще не мог получить доступ к этому через публичный IP, работая над этим сейчас ...

0 голосов
/ 10 февраля 2011

Возможно, сокет сервера привязан только к адресу localhost.Вы можете привязать его к определенному IP-адресу, используя форму конструктора с тремя аргументами.

...