Java套接字:没有可用的缓冲区空间(达到最大连接数?)

mac*_*ery 5 java sockets multithreading

我有一个大问题.我开发了一个客户端 - 服务器应用程序.客户端线程将序列化对象发送到服务器,服务器发回序列化对象.目前我正在使用一个服务器和10个客户端线程,大约30秒后,我从每个客户端线程收到错误消息(IOException):

没有可用的缓冲区空间(达到最大连接数?):connect

如果我正在寻找netstat,那么我看到有很多连接被创建,并且它正在增长和增长,并且所有连接都处于TIME_WAIT状态.

我不知道为什么.我每次都在finally块中关闭服务器和客户端中的套接字.这是一些代码:

在socketHandlerThread中的服务器中:

ServerSocket serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(5000);
while(true) {
       Socket socket = serverSocket.accept();
}
Run Code Online (Sandbox Code Playgroud)

然后将新套接字放在LinkedBlockingQueue上,工作线程接受套接字并执行以下操作:

try {
      outputStream = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
      outputStream.flush();
      inStream = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
      ClientRequest clientRequest = (ClientRequest) inStream.readObject();
...
      outputStream.writeObject(serverResponse);
      outputStream.flush();
} catch....
} finally {
                if (inStream != null) {
                    inStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
                if (socket != null) {
                    socket.close();
                }
}
Run Code Online (Sandbox Code Playgroud)

在客户端,我有以下代码:

    try {
        socket = new Socket(host, port);
        outputStream = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
        outputStream.flush();
        inputStream = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
        outputStream.writeObject(request);
        outputStream.flush();
        Object serverResponse = inputStream.readObject();
   } catch....
   } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
            if (socket != null) {
                socket.close();
            }
   }
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙吗?我真的不知道自己犯了什么错误.我似乎插座没有关闭,但我不知道为什么.

可能是我将套接字放在服务器端的队列上以便以某种方式复制套接字的问题?

编辑:如果我将客户端和服务器分别放在运行Linux AMI的其他Amazon EC2经典实例上,那么它可以工作.这可能是Windows的一个问题,或者只是我在同一台机器(我的本地电脑)上运行客户端和服务器的问题?

有人在我的代码中看到了一个错误吗?

编辑2:如上所述在EC2实例上它可以工作,但如果我使用netstat它仍然显示很多行说TIME_WAIT.

这是截图:

https://drive.google.com/file/d/0BzERdJrwWrNCWjhReGhpR2FBMUU/view?usp=sharing

https://drive.google.com/file/d/0BzERdJrwWrNCOG1TWGo5YmxlaTg/view?usp=sharing

第一个截图来自windows."WARTEND"表示"等待"(它是德语).

第二个屏幕截图来自Amazon EC2(左侧是客户端计算机,右侧是服务器计算机).

use*_*421 3

两端连接关闭进入TIME-WAIT 。出于数据完整性原因,它会持续几分钟。

如果缓冲区问题是由于服务器上的 TIME-WAIT 状态引起的,则解决方案是使服务器成为第一个收到关闭消息的对等方。这会将 TIME-WAIT 状态转移到客户端,这是良性的。

您可以通过将服务器端请求处理放入循环中来做到这一点,以便它可以处理每个连接的多个请求,并且服务器仅在到达套接字上的流末尾时才关闭套接字。

for (;;)
{
    try
    {
        ClientRequest clientRequest = (ClientRequest) inStream.readObject();
        ...
        outputStream.writeObject(serverResponse);
        outputStream.flush();
    }
    catch (EOFException exc)
    {
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您随后在客户端实现连接池,您将大量减少连接数量,这将进一步减少缓冲区问题的发生率。