Если я выполнил тест JUnit ниже БЕЗ строки «inputStream.close()» (см. Ниже), можно обработать более 60000 запросов (тогда я убил процесс). С этой линии, мне не удалось сделать более 15000 запросов, из-за:Клиент SocketInputStream.close() приводит к увеличению потребления ресурсов?
java.net.SocketException: No buffer space available (maximum connections reached?): connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:529)
at java.net.Socket.connect(Socket.java:478)
at java.net.Socket.<init>(Socket.java:375)
at java.net.Socket.<init>(Socket.java:189)
at SocketTest.callServer(SocketTest.java:60)
at SocketTest.testResourceConsumption(SocketTest.java:52)
Я запустить его на Windows, перед началом теста я жду NETSTAT список, чтобы вернуться к нормальной жизни.
Вопросы:
- почему зовут socketInputStream.close() на стороне клиента вреде в данном случае?
- или что не так с кодом?
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import junit.framework.TestCase;
public class SocketTest extends TestCase {
private static final int PORT = 12345;
private ServerSocket serverSocket;
public void setUp() throws Exception {
serverSocket = new ServerSocket(PORT);
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
try {
final Socket socket = serverSocket.accept();
new Thread(new Runnable() {
@Override
public void run() {
try {
OutputStream outputStream = socket.getOutputStream();
for(int i = 0; i < 100; i++) {
outputStream.write(i);
}
outputStream.close();
// in fact the previous line calls this already:
// socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}).start();
}
public void testResourceConsumption() throws Exception {
for (int i=0; i<1000000; i++) {
callServer();
if (i % 1000 == 0) {
System.out.println(i);
}
}
}
private void callServer() throws Exception {
Socket clientSocket = new Socket("localhost", PORT);
InputStream inputStream = clientSocket.getInputStream();
for (int i = 0; i < 100; i++) {
assertEquals(i, inputStream.read());
}
///////////////// THIS LINE IS INTERESTING
inputStream.close();
// in fact the previous line calls this already:
// clientSocket.close();
}
public void tearDown() throws Exception {
serverSocket.close();
}
}
Конечно, вы не должны это задом наперед? – EJP
Можете ли вы предоставить дополнительную информацию о версии Windows, платформе 32 или 64 бит и java-версии? – sibnick
Просто для справки, я проверил ваш тест на Ubuntu 15.04. Он выполнил все миллионы итераций без ошибок. Примерно 28000 сокетов существовали в состоянии TIME_WAIT в любой момент времени во время выполнения. (это связано со скоростью выполнения и открытием новых сокетов) – dsh