I have been investigating this problem for hours and hours, and I cannot come up with a decent solution or explanation of why this exception (java.net.SocketException: Socket closed) is being thrown. My last approach is now to ask you guys.
I created a simple client-server application for testing (for example, a “real” application uses the same logic), see below.
If I repeat calling the same test script (for example, via the TestNG invocationcount annotation parameter or using a simple for loop), at some point there will be java.net.SocketException: Socket closed .
The following test case just starts the server (opens the server socket), waits a couple of milliseconds, and then closes the socket again. Closing the server socket involves opening the socket so that the server returns from the ServerSocket.accept () method (see "Shutting down the server" ()).
Perhaps this is a multithreading issue with the code immediately after ServerSocket.accept () - line. Therefore, I temporarily surrounded him with a synchronized block - also did not help.
Do you have an idea why this exception gets?
Best Chris
Server.java is as follows:
package multithreading;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import org.apache.log4j.Logger;
public class Server {
private ServerSocket serverSocket;
private boolean isShuttingDown;
private final static Logger logger = Logger.getLogger(Server.class);
public void start() throws Exception {
try {
serverSocket = new ServerSocket(5000);
isShuttingDown = false;
} catch (Exception e) {
throw new RuntimeException("Starting up the server failed - aborting", e);
}
while (true) {
try {
Socket socket = serverSocket.accept();
if (!isShuttingDown) {
new Thread(new EchoRequestHandler(socket)).start();
} else {
logger.info("Server is going to shutdown");
break;
}
} catch (IOException e) {
logger.error("Error occured while waiting for new connections, stopping server", e);
throw e;
}
}
}
public synchronized boolean isRunning() {
if (serverSocket != null && serverSocket.isBound() && !serverSocket.isClosed() && !isShuttingDown) {
return true;
}
return false;
}
public synchronized void shutdown() throws IOException {
if (isRunning()) {
isShuttingDown = true;
if (serverSocket != null && !serverSocket.isClosed()) {
try {
new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort()).close();
serverSocket.close();
} catch (IOException e) {
logger.error("Closing the server socket has failed - aborting now.", e);
throw e;
}
}
} else {
throw new IOException("Server socket is already closed which should not be the case.");
}
}
}
The test class does the following:
package multithreading;
import java.io.IOException;
import org.testng.annotations.Test;
public class Testing {
@Test
public void loadTest() throws InterruptedException, IOException {
for (int i = 0; i < 10; i++) {
final Server s = new Server();
new Thread(new Runnable() {
@Override
public void run() {
try {
s.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
Thread.sleep(500);
gracefullyShutdownServer(s);
Thread.sleep(1000);
}
}
private void gracefullyShutdownServer(final Server server) throws InterruptedException {
try {
server.shutdown();
while (server.isRunning()) {
Thread.sleep(500);
}
} catch (IOException e) {
System.err.println(e);
}
}
}
The stack trace is as follows:
ERROR 2011-03-13 16:14:23,537 [Thread-6] multithreading.Server: Error occured while waiting for new connections, stopping server
java.net.SocketException: Socket closed
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390)
at java.net.ServerSocket.implAccept(ServerSocket.java:453)
at java.net.ServerSocket.accept(ServerSocket.java:421)
at multithreading.Server.start(Server.java:26)
at multithreading.Testing$1.run(Testing.java:18)
at java.lang.Thread.run(Thread.java:680)
java.net.SocketException: Socket closed
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390)
at java.net.ServerSocket.implAccept(ServerSocket.java:453)
at java.net.ServerSocket.accept(ServerSocket.java:421)
at multithreading.Server.start(Server.java:26)
at multithreading.Testing$1.run(Testing.java:18)
at java.lang.Thread.run(Thread.java:680)