使用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通道)比仅对服务器使用线程更好吗?
错误是实际上假设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)