gpt4 book ai didi

客户端与服务器断开连接时 Java 套接字写入错误

转载 作者:行者123 更新时间:2023-12-02 09:47:50 24 4
gpt4 key购买 nike

我正在用 Java 开发一个聊天应用程序,到目前为止一切正常,除了当客户端断开连接并且其他客户端发送消息时会弹出此错误:

  java.net.SocketException: Software caused connection abort: socket write error
at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
at java.base/java.io.DataOutputStream.write(DataOutputStream.java:107)
at java.base/java.io.DataOutputStream.writeUTF(DataOutputStream.java:401)
at java.base/java.io.DataOutputStream.writeUTF(DataOutputStream.java:323)
at com.terkea/com.terkea.system.server.ClientThread.run(ClientThread.java:65)
at java.base/java.lang.Thread.run(Thread.java:835)

这是我的服务器线程:

@Override
public void run() {
try {
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());

while (!socket.isClosed()) {
try {
String input = in.readUTF();
if (Message.fromJSON(input).getUserName().equals("REGISTER")) {
Message specialMessage = Message.fromJSON(input);
specialMessage.setUserName("SERVER");

Client test = Client.fromJSON(specialMessage.getMessage());
test.setIp(socket.getInetAddress().toString());
test.setListening_port(String.valueOf(socket.getPort()));
specialMessage.setMessage(Client.toJSON(test));

input = Message.toJSON(specialMessage);

}
for (ClientThread thatClient : server.getClients()) {
DataOutputStream outputParticularClient = new DataOutputStream(thatClient.getSocket().getOutputStream());
outputParticularClient.writeUTF(input);
}
} catch (IOException e) {
e.printStackTrace();
}
}

} catch (IOException e) {
e.printStackTrace();
}
}

和客户:

public void createClient() {

try {
socket = new Socket(getHost(), portNumber);

DataInputStream in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
Message registerclient = new Message("REGISTER", Client.toJSON(getClient()));
out.writeUTF(Message.toJSON(registerclient));

new Thread(() -> {
while (!socket.isClosed()) {
try {
if (in.available() > 0) {
String input = in.readUTF();
Message inputMessage = Message.fromJSON(input);
if (inputMessage.getUserName().equals("SERVER")) {
System.err.println(Client.fromJSON(inputMessage.getMessage()));
allClientsConnected.add(Client.fromJSON(inputMessage.getMessage()));
} else {
chat.add(inputMessage);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}

错误对应于outputPspecialClient.writeUTF(input);

我的目标是消除这个错误,如果可能的话,有人可以告诉我一种检查客户端何时断开连接的方法吗?我在这里发现了一些类似的问题,他们的解决方案是检查 if (socket.getInputStream().read()!=-1)但是当我这样做时,整个程序卡住并且 GUI 停止工作。

最佳答案

您可能想考虑扩展您的特殊消息功能,而不是使用用户名来传递“REGISTER”,而是使用诸如 messageType 之类的内容来实现此目的。通过这种方式,您可以根据类型配置处理程序来执行许多操作。例如:

MessageType { REGISTER, UNREGISTER, READ_RECEIPT, ... }

然后你可以得到类似的东西:

RegisterHandler {}
UnregisterHandler{}

并最终将它们扩展为具有一些功能,例如 facebook/whatsapp(/ICQ 哈哈):

TypingHandler {} // Other user gets a message saying that I am typing to them

从这里,您可以实现 UNREGISTER 来执行您想要的操作。就像第一条评论所说,您应该捕获 SocketException 并手动取消注册该客户端,这样它就不会再发生了。但您还应该尝试先发制人地发送

{
messageType: UNREGISTER,
from: Client1
to: server|null,
data: {}
}

以便您的服务器可以在异常发生之前将其删除。如果您对此感兴趣,这还可以让您处理离线消息。

关于客户端与服务器断开连接时 Java 套接字写入错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56525745/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com