[使用子网IP地址时Java套接字主机已关闭

问题描述 投票:0回答:1

使用JDK 10,试图编写一个客户端/服务器程序,该程序将使用TCP / IP套接字在多台计算机上单独运行。

所有计算机都应位于同一本地子网192.168.1.x(其中x可以在1到254之间变化)。

各个服务器从客户端程序接收一个字符串并打印出该字符串。

ServerThread

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()));
            }
        }
    }

}

客户:

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

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("192.168.1.2", "6500");
    }
}

最初,对于一台机器,当我用"192.168.1.2"替换"localhost"(它输出我输入的任何字符串)时,这是有效的...

但是使用"192.168.1.2",我得到了:

Exception in thread "main" java.net.SocketException: Host is down (connect failed)
    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:213)
    at com.sample.Client.connect(Client.java:11)
    at com.sample.Client.main(Client.java:24)

为什么这不适用于特定的子网地址(它适用于"localhost"

还有其他一些Java API(例如,响应流或NIO通道)比仅对服务器使用线程更好吗?

java sockets java-10
1个回答
0
投票

错误是实际上假设Socket构造函数同时使用IP和主机名:

new Socket("192.168.1.2", 6500)

无效,因为它需要主机名。从this文档:

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)
© www.soinside.com 2019 - 2024. All rights reserved.