所以我有两个线程,一个是服务器套接字,第二个是客户端。服务器使用
readAllBytes()
从客户端读取一些消息,然后使用 write()
返回该消息,然后使用 flush()
。客户端基本上做同样的事情,但顺序相反。这是代码:
package org.example;
import java.io.*;
import java.net.*;
public class Main {
public static void main(String[] args) {
new Thread(() -> {
try (ServerSocket serverSocket = new ServerSocket(8080);
Socket socket = serverSocket.accept();
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream()) {
System.out.println("SERVER: reading message...");
byte[] bytes = in.readAllBytes();
System.out.println("SERVER: message from the client: " + new String(bytes));
System.out.println("SERVER: sending message back...");
out.write(bytes);
out.flush();
System.out.println("SERVER: message sent back.");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try (Socket socket = new Socket("localhost", 8080);
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream()) {
System.out.println("CLIENT: sending message...");
out.write("hello world".getBytes());
out.flush();
System.out.println("CLIENT: message sent.");
System.out.println("CLIENT: reading response from the server...");
byte[] bytes = in.readAllBytes();
System.out.println("CLIENT: response from the server: " + new String(bytes));
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
但是这是输出:
SERVER: reading message...
CLIENT: sending message...
CLIENT: message sent.
CLIENT: reading response from the server...
虽然客户端说他发送了消息,但服务器没有回复,我不知道为什么。如果我这样做,让服务器只读取来自客户端的消息并且不发回任何内容,并且我让客户端只发送消息而不回读任何内容:
new Thread(() -> {
try (ServerSocket serverSocket = new ServerSocket(8080); Socket socket = serverSocket.accept(); InputStream in = socket.getInputStream()) {
System.out.println("SERVER: reading message...");
byte[] bytes = in.readAllBytes();
System.out.println("SERVER: message from the client: " + new String(bytes));
} catch (Exception e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try (Socket socket = new Socket("localhost", 8080); OutputStream out = socket.getOutputStream()) {
System.out.println("CLIENT: sending message...");
out.write("hello world".getBytes());
out.flush();
System.out.println("CLIENT: message sent");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
一切都会很好:
SERVER: reading message...
CLIENT: sending message...
CLIENT: message sent.
SERVER: message from the client: hello world
readAllBytes
读取所有字节。服务器如何知道“hello world”是客户端要发送的全部数据?它没有,所以它等待更多。 readAllBytes
将读取所有内容,直到流关闭。但是如果你关闭流,你也将关闭套接字,这意味着客户端将无法读取服务器的响应。
所以你需要建立某种方式来指示“消息到此结束”,以便服务器可以停止读取消息,并开始发送响应。这可以是特定字节或特定字节序列。或者,可以使用
readNBytes
让服务器每次仅读取固定数量的字节。
既然您要发送文本,我建议您用真正理解text的东西包装输入/输出流,而不是使用原始字节。例如,您可以使用
Scanner
进行读取,使用 PrintStream
进行写入。然后使用行分隔符作为“消息的结尾”(println
和nextLine
)非常方便。
try (ServerSocket serverSocket = new ServerSocket(8080);
Socket socket = serverSocket.accept();
Scanner in = new Scanner(socket.getInputStream());
PrintStream out = new PrintStream(socket.getOutputStream())) {
System.out.println("SERVER: reading message...");
String s = in.nextLine();
System.out.println("SERVER: message from the client: " + s);
System.out.println("SERVER: sending message back...");
out.println(s);
out.flush();
System.out.println("SERVER: message sent back.");
} catch (Exception e) {
e.printStackTrace();
}
try (Socket socket = new Socket("localhost", 8080);
PrintStream out = new PrintStream(socket.getOutputStream());
Scanner in = new Scanner(socket.getInputStream())) {
System.out.println("CLIENT: sending message...");
out.println("hello world");
out.flush();
System.out.println("CLIENT: message sent.");
System.out.println("CLIENT: reading response from the server...");
String s = in.nextLine();
System.out.println("CLIENT: response from the server: " + s);
} catch (Exception e) {
e.printStackTrace();
}