0

我在 WinServer 2008 机器上有一个简单的多客户端 java 服务器,它工作正常,但是在看似随机的时间(天)之后,服务器停止接受任何连接,我不知道为什么。

它没有捕获任何异常,它不会崩溃,它只是不接受任何连接,我认为这是被 GC 处理的 serversocket,所以我将其设为全局但无济于事。它似乎也不是 TCP 耗尽,因为几个小时没有人连接,它仍然不接受任何连接,我也将 setReuseAddress 设置为 true,但它一直在做同样的事情。

让它再次工作的唯一方法是重新启动 java 服务器应用程序(不需要重新启动机器)并且它再次正常工作......一段时间。

这是我与情况相关的代码:

        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");
    }

编辑:更改代码

            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();
4

2 回答 2

1

您在接受循环中阻塞了客户端 I/O。一个从不发送任何东西的客户端可以停止整个系统。您在接受循环中应该做的就是接受连接并启动线程。唯一的阻塞操作应该是 accept() 本身。客户端 I/O 应该在单独的线程中完成。

于 2012-09-05T23:40:32.923 回答
0

您正在泄漏套接字。您的关闭将被异常跳过。使用 finally 块来释放资源。

while(...) {
   Socket sckt;
   try {
      sckt = ...
      ...
   } catch(Exception e) {
   } finally {
       sckt.close();
   }
}
于 2012-09-05T04:43:03.823 回答