【发布时间】:2019-06-07 11:07:19
【问题描述】:
这是我第一次使用套接字,为了更好地了解正在发生的事情,我决定构建一个可以支持多个用户的客户端服务器聊天应用程序。
一开始我用DataInputStream / DataOutputStream交流,一切正常。但我想切换到ObjectStream,这就是问题所在。一旦我将所有DataInputStream / DataOutputStream 替换为ObjectInputStream / ObjectOutputStream,我将无法再打印检索到的数据。
这是我之前使用的代码,它可以工作(DataStream):
服务器:
try {
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeUTF("HI FROM SERVER");
while (!socket.isClosed()) {
try {
if (in.available() > 0) {
String input = in.readUTF();
for (ClientThread thatClient : server.getClients()){
DataOutputStream outputParticularClient = new DataOutputStream(thatClient.getSocket().getOutputStream());
outputParticularClient.writeUTF(input + " GOT FROM SERVER");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
客户:
try {
socket = new Socket("localhost", portNumber);
DataInputStream in = new DataInputStream(socket.getInputStream());
new Thread(()->{
while(!socket.isClosed()){
try {
if (in.available() > 0){
String input = in.readUTF();
System.out.println(getUserName() + " > " + input);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
这就是我尝试使用 ObjectStream 执行相同想法的方式:
服务器:
try {
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
while (!socket.isClosed()) {
try {
if (in.available() > 0) {
Message input;
try {
input = (Message)in.readObject();
if (input.equals(null)){
System.err.println("SERVER RETRIEVED NULL OBJECT");
}
for (ClientThread thatClient : server.getClients()){
ObjectOutputStream outputParticularClient = new ObjectOutputStream(thatClient.getSocket().getOutputStream());
outputParticularClient.writeObject(input);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
客户:
try {
socket = new Socket(getHost(), portNumber);
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
new Thread(()->{
while(!socket.isClosed()){
try {
if (in.available() > 0){
Message input = null;
try {
input = (Message)in.readObject();
if (input.equals(null)){
System.err.println("CLIENT RETRIEVED NULL OBJECT");
}
System.out.println("CLIENT " + input.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
我觉得这与这个 if 语句 if (in.available() > 0) 有关,但我不能准确地说出发生了什么。
【问题讨论】:
-
尝试在
outputParticularClient.writeObject(input);之后添加刷新/关闭(流永远不会关闭) -
我试过了,但还是不行。我让它们保持打开状态的原因是因为只要应用程序运行,它们就会进行通信。一旦关闭,监听器也会关闭。
-
“我无法再打印检索到的数据”不是问题描述。您对
available()的使用毫无意义。 -
StreamCorrupted 与
available()的使用无关。你一定做错了什么。尽管如此,发送数据很可能需要刷新(否则,刷新仅在缓冲区已满或流关闭时发生)。 -
正如@user207421 所说,使用
available毫无意义。StreamCorruptedException应该是由重新创建新的 ObjectOutputStreams 引起的,如question 的答案中所述。
标签: java sockets stream client-server