[英]How to fix: java.net.SocketException: An established connection was aborted by the software in your host machine
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.ServerSocket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(12345, 3);
Socket socket = serverSocket.accept(); // incoming request
new WorkerThread(socket).start();
}
}
class WorkerThread extends Thread {
private Socket socket;
public WorkerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); // line 28
// handle the request using oos and ois
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.net.Socket;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Client {
public static void main(String[] args) throws Exception {
try (Socket socket = new Socket("192.168.1.3", 12345)) {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
// ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); // line 11
// send some data only using oos
}
}
}
java.net.SocketException: An established connection was aborted by the software in your host machine
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:325)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:966)
at java.base/java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2908)
at java.base/java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2924)
at java.base/java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3421)
at java.base/java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:959)
at java.base/java.io.ObjectInputStream.<init>(ObjectInputStream.java:397)
at WorkerThread.run(Server.java:28)
The WorkerThread
seems to be causing the issue, since the SocketException
is not thrown if the code in the code of the WorkerThread#run
method is placed in the Server#main
method. WorkerThread
似乎是导致问题的原因,因为如果将WorkerThread#run
方法的代码中的代码放在Server#main
方法中,则不会引发SocketException
。 See Note below.请参阅下面的注释。
The intent here is to have a separate Thread (other than the main Thread of the Server) handle each request as it comes, therefore the WorkerThread
receives a reference to the Socket
associated with the incoming connection.这里的目的是让一个单独的线程(除了服务器的主线程)处理每个请求,因此
WorkerThread
接收对与传入连接关联的Socket
的引用。
The WorkerThread
needs to open both oos
and ois
(even though they might not be both strictly needed for communication) because opening only the ois
won't work. WorkerThread
需要同时打开oos
和ois
(即使它们可能并非都严格需要用于通信),因为只打开ois
是行不通的。 Further reading on why this happens . 进一步阅读为什么会发生这种情况。
What is the underlying cause of this issue?这个问题的根本原因是什么? Is there a way to fix the problem other than the hacky (?) solution presented below?
除了下面介绍的 hacky (?) 解决方案之外,还有其他方法可以解决问题吗?
Running the above Client with this Server does not throw the Exception:使用此服务器运行上述客户端不会引发异常:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.ServerSocket;
public class NonThreadedServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(12345, 3);
Socket socket = serverSocket.accept(); // incoming request
try {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
// handle the request using oos and ois
} catch (IOException e) {
e.printStackTrace();
}
}
}
Uncomment line 11 of Client
, ie create an ObjectInputStream
, even though it is not strictly needed for the communication:取消注释
Client
的第 11 行,即创建一个ObjectInputStream
,即使通信并不严格需要它:
import java.net.Socket;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Client {
public static void main(String[] args) throws Exception {
try (Socket socket = new Socket("192.168.1.3", 12345)) {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); // line 11
// send some data only using oos
}
}
}
As mentioned in the question, I don't know what the underlying issue is or whether this solution is the correct one.如问题中所述,我不知道根本问题是什么,也不知道这个解决方案是否正确。 If it isn't, I'll make sure to mark another answer as the accepted one.
如果不是,我会确保将另一个答案标记为已接受的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.