我正在做一个简单的回声聊天和服务器,但类send
中的方法receive
和Connection
不适用于ObjectInputStream
和ObjectOutputStream
,但PrintWriter
和BufferedReader
工作正常。
现在我正在尝试使用套接字来理解序列化,帮助我理解为什么这段代码不起作用:
客户端
public class Client {
private Connection connection;
private String getServerAddress() {
return "localhost";
}
private int getServerPort() {
return 4444;
}
public void run() {
BufferedReader bis = new BufferedReader(new InputStreamReader(System.in));
try {
connection = new Connection(new Socket(getServerAddress(), getServerPort()));
SocketThread socketThread = new SocketThread();
socketThread.setDaemon(true);
socketThread.start();
while (true) {
String text = bis.readLine();
if (text.equalsIgnoreCase("exit"))
break;
connection.send(text);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.run();
}
public class SocketThread extends Thread {
@Override
public void run() {
try {
while (true) {
String message = connection.receive();
System.out.println(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
连接
public class Connection implements Closeable {
private final Socket socket;
private final ObjectInputStream in;
private final ObjectOutputStream out;
public Connection(Socket socket) throws Exception {
this.socket = socket;
this.in = new ObjectInputStream(socket.getInputStream());
this.out = new ObjectOutputStream(socket.getOutputStream());
}
public void send(String message) throws Exception {
out.writeObject(message);
}
public String receive() throws Exception {
return (String) in.readObject();
}
@Override
public void close() throws IOException {
in.close();
out.close();
socket.close();
}
}
服务器
public class Server {
public static void main(String[] args) {
int port = 4444;
try (ServerSocket serverSocket = new ServerSocket(port)) {
while (true) {
Socket socket = serverSocket.accept();
new Handler(socket).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static class Handler extends Thread {
private Socket socket;
public Handler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (Connection connection = new Connection(socket)) {
while (true) {
String message = connection.receive();
if (message.equals("exit"))
break;
System.out.println(message);
connection.send("Echo: " + message);
}
} catch (Exception e) {
}
}
}
}
答案 0 :(得分:0)
这是因为ObjectInputStream
阻止尝试在其构造函数中读取由ObjectOutputStream
写入的流标头,并且您在输出流之前创建了两个输入流。您可以通过切换创建对象流的顺序来解决此问题:
this.out = new ObjectOutputStream(socket.getOutputStream());
this.in = new ObjectInputStream(socket.getInputStream());
javadoc for the ObjectOutputStream
constructor还指出您可能希望在创建流后刷新流以确保发送标头。