【发布时间】:2014-10-17 07:24:13
【问题描述】:
我有一个大问题。我开发了一个客户端-服务器应用程序。客户端线程向服务器发送一个序列化的对象,服务器返回一个序列化的对象。目前我正在使用一台服务器和 10 个客户端线程,大约 30 秒后,我从每个客户端线程(IOException)收到错误消息:
没有可用的缓冲区空间(已达到最大连接数?):连接
如果我在 netstat 中查看,那么我会看到创建了很多连接,而且它还在不断增长,所有连接都处于 TIME_WAIT 状态。
我不知道为什么。我每次在 finally 块中关闭服务器和客户端中的套接字。这是一些代码:
在我的 socketHandlerThread 中的服务器中:
ServerSocket serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(5000);
while(true) {
Socket socket = serverSocket.accept();
}
然后将新套接字放在 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();
}
}
在客户端我有以下代码:
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();
}
}
有人可以帮忙吗?我真的不知道我犯了什么错误。我似乎没有关闭套接字,但我不知道为什么。
可能是我将套接字放在服务器端的队列中以便以某种方式复制套接字的问题吗?
编辑:如果我将客户端和服务器分别放在运行 Linux AMI 的不同 Amazon EC2 经典实例上,那么它可以工作。这可能是 Windows 的问题,还是仅仅是我在同一台机器(我的本地电脑)上运行客户端和服务器的问题?
有人看到我的代码中有错误吗?
Edit2:如上所述,它在 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”的意思是“WAITING”(德语)。
第二个屏幕截图来自 Amazon EC2(左侧是客户端机器,右侧是服务器机器)。
【问题讨论】:
-
只是一个想法——为什么不使用 RMI? RMI 处理套接字线程问题。
-
不幸的是我不得不使用这种风格。
-
netstat 到底说了什么? “等待”不是港口状态。
-
@EJP 我已经更新了我的问题
-
但是你还没有回答我的问题。 netstat 可以打印十几个状态,但“等待”不是其中之一。有几个名称中带有
_WAIT。是哪个?
标签: java multithreading sockets