Java Сокеты не могут получить доступ к серверу с использованием IP-адреса Su bnet - PullRequest
1 голос
/ 05 апреля 2020

Используя JDK 10, я пытаюсь написать клиент-серверную программу, которая будет запускаться отдельно на нескольких компьютерах с использованием сокетов TCP / IP.

Все компьютеры должны быть в одной локальной папке su bnet 192.168.1. x (где x может варьироваться от 1 до 254).

Отдельные серверы получают строку из клиентской программы и распечатывают строку.

ServerThread. java:

import java.io.IOException;
import java.net.ServerSocket;
import java.util.concurrent.Executors;

public class ServerThread implements Runnable {

    private Socket socket;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        System.out.println("Connected" + socket);
        try {
            var in = new Scanner(socket.getInputStream());
            var out = new PrintWriter(socket.getOutputStream(), true);
            while (in.hasNextLine()) {
                out.println(in.nextLine());
            }
        }
        catch (Exception e) {
            System.out.println("Error:" + socket);
        }
        finally {
            try {
                socket.close();
            }
            catch (IOException e) {
            }
            System.out.println("Closed: " + socket);
        }
    }

    public static void main(String[] args) throws IOException {
        try (var listener = new ServerSocket(6500)) {
            System.out.println("Server has started...");
            var pool = Executors.newFixedThreadPool(20);
            while (true) {
                pool.execute(new ServerThread(listener.accept()));
            }
        }
    }

}

Первоначально он работал бы с "localhost" как hostName:

public class Client {

    public static void connect(String hostName, String portNumber) throws Exception {
        int port = Integer.parseInt(portNumber);
        try (var socket = new Socket(hostName, port)) {
            System.out.println("Enter lines of text then Ctrl+D or Ctrl+C to quit");
            var scanner = new Scanner(System.in);
            var in = new Scanner(socket.getInputStream());
            var out = new PrintWriter(socket.getOutputStream(), true);
            while (scanner.hasNextLine()) {
                out.println(scanner.nextLine());
                System.out.println(in.nextLine());
            }
        }
    }

    public static void main(String[] args) throws Exception {
        Client.connect("localhost", "6500");
    }
}

Теперь при использовании new Socket(InetAddress.getByName(ipAddress), port) я получаю java.net.ConnectException: Connection refused Исключение:

import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;

public class Client {

    public static void connect(String iPAddress, String portNumber) throws Exception {
        int port = Integer.parseInt(portNumber);

        try (var socket = new Socket(InetAddress.getByName(iPAddress), port)) {
            System.out.println("Enter lines of text then Ctrl+D or Ctrl+C to quit");
            var scanner = new Scanner(System.in);
            var in = new Scanner(socket.getInputStream());
            var out = new PrintWriter(socket.getOutputStream(), true);
            while (scanner.hasNextLine()) {
                out.println(scanner.nextLine());
                System.out.println(in.nextLine());
            }
        }
    }

    public static void main(String[] args) throws Exception {
        Client.connect("192.168.1.1", "6500");
    }
}

Exception in thread "main" java.net.ConnectException: Connection refused (Connection refused)
    at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:400)
    at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:243)
    at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:225)
    at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:402)
    at java.base/java.net.Socket.connect(Socket.java:591)
    at java.base/java.net.Socket.connect(Socket.java:540)
    at java.base/java.net.Socket.<init>(Socket.java:436)
    at java.base/java.net.Socket.<init>(Socket.java:246)
    at com.sample.Client.connect(Client.java:13)
    at com.sample.Client.main(Client.java:26)

Однако, когда я пытаюсь использовать "192.168.1.2", ничего не происходит (даже не выводится: Enter lines of text then Ctrl+D or Ctrl+C to quit)

И в конце концов, Время ожидания истекает, выбрасывая это исключение:

Exception in thread "main" java.net.ConnectException: Operation timed out (Connection timed out)
    at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:400)
    at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:243)
    at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:225)
    at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:402)
    at java.base/java.net.Socket.connect(Socket.java:591)
    at java.base/java.net.Socket.connect(Socket.java:540)
    at java.base/java.net.Socket.<init>(Socket.java:436)
    at java.base/java.net.Socket.<init>(Socket.java:246)
    at com.sample.Client.connect(Client.java:13)
    at com.sample.Client.main(Client.java:26)


Вопросы:

  1. Почему выдается это исключение: java.net.ConnectException: Connection refused при использовании 192.168.1.1 и java.net.ConnectException: Operation timed out (Connection timed out) при использовании любого di git, отличного от 1, для хоста (последний di git), например, 192.168.1.2?

  2. Существуют ли другие Java 10 AP Я (например, реактивные потоки или каналы NIO), что лучше, чем просто использовать потоки для сервера?

Ответы [ 3 ]

0 голосов
/ 05 апреля 2020

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

Я человек Linux, поэтому знаю только о Linux utilities:

"sudo netstat -tpln", чтобы выяснить, прослушивает ли ваше серверное приложение желаемый порт, и, что наиболее важно, оно должно прослушивать IP 0.0.0.0, а не только 127.0.0.1 для того, чтобы сетевые компьютеры могли подключаться к нему.

"sudo iptables -vnL", чтобы узнать, не блокирует ли межсетевой экран внешние исходные соединения с вашими серверными приложениями. Если это так, то клиентское приложение в той же системе, где находится серверное приложение, сможет обмениваться данными, но не то же клиентское приложение в других системах в той же сети.

По моему опыту, эта отладка помогает решить такие проблемы более чем в 90% случаев, и это обычно не проблема программирования. Я надеюсь, что эта информация поможет.

0 голосов
/ 08 апреля 2020

Понял - мой маршрутизатор / брандмауэр назначает разные компьютеры в моей сети различным IP-адресам на основе Su bnet, но не обязательно назначит второй компьютер (последовательно):

191.168.1.2

Запустил ifconfig и обнаружил конкретный IP-адрес на основе Su bnet, который был 192.168.1.x, реальное значение "x" было опущено из соображений безопасности.

0 голосов
/ 05 апреля 2020

Ошибка заключается в предположении, что конструктор Socket использует как IP, так и имя хоста, на самом деле:

new Socket("192.168.1.2", 6500)

не работает, поскольку ожидает имя хоста. С это до c:

host - the host name, or null for the loopback address.
. . .
public Socket(String host,int port) throws UnknownHostException, IOException

Что вы должны использовать:

new Socket(InetAddress.getByName("192.168.1.2"), 6500)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...