I have a simple multi-client java server on a WinServer 2008 machine and it's working fine, but after a seemingly random ammount of time (days) the server stops accepting any connections and i can't figure out why.
It doesn't catch any exceptions, it doesn't crash, it just doesn't accept any connections, i thought it was the serversocket being GC'd so i made it global but to no avail. It does not seem to be TCP exhaustion either, since there hasn't been anyone connected for hours and it still doesn't accept any connections and i also have set the setReuseAddress to true but it keeps doing the same thing.
The only way to make it work again is to reboot the java server application (doesn't need to reboot the machine) and it's working fine again...for a while.
here's my code relevant to the situation:
try
{
ServerSocket srvr = new ServerSocket(PORT);
while (isAlive)
{
Socket skt = srvr.accept();
this.bw = new PrintWriter(skt.getOutputStream(), true);
this.br = new BufferedReader(new InputStreamReader(skt.getInputStream()));
String msg = br.readLine();
//process msg
skt.close();
}
}
catch (Exception e)
{
System.out.println("Error");
}
edit: changed code
while (isAlive)
{
Socket skt = srvr.accept();
skt.setSoTimeout(10000);
acceptConnection(skt);
}
public void acceptConnection(final Socket skt) throws Exception
{
Thread discConn = new Thread()
{
public void run()
{
try
{
PrintWriter bw = new PrintWriter(skt.getOutputStream(), true);
BufferedReader br = new BufferedReader(new InputStreamReader(skt.getInputStream()));
String msg = br.readLine();
//process msg
}
catch (SocketTimeoutException ste)
{
//
}
catch (SocketException se)
{
//
}
catch (Exception e)
{
System.out.println("ERROR");
}
finally
{
try
{
skt.close();
}
catch (IOException e)
{
System.out.println("ERROR");
}
}
}
};
discConn.start();
解决方案
You are blocking on client I/O in the accept loop. One client that never sends anything can stop the whole system. All you should do in the accept loop is accept connections and start threads. The only blocking operation should be the accept() itself. Client I/O should be done in a separate thread.