Java Networking "Connection Refused: Connect"

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

Сервер:

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, поэтому он выглядит как стандартный заблокированный порт, и никакой другой подозрительный пакетный трафик не происходит.

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

Ответ 1

Для чего это стоит, ваш код отлично работает в моей системе.

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

Ответ 2

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

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

  • Сервер не запущен.

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

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

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

  • Неправильный протокол в строке подключения.

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

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

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

Ответ 3

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

Ответ 4

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

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

Но я до сих пор не смог получить доступ к публичному IP-адресу, работая над ним сейчас...

Ответ 5

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

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

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... }

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