Wenn ich den JUnit-Test unten OHNE die Zeile "inputStream.close()" (siehe unten) ausführen, können mehr als 60000 Anfragen verarbeitet werden (Ich habe den Prozess dann getötet). Mit dieser Linie, habe ich nicht verwalten mehr als 15.000 Anfragen machen, weil:Client SocketInputStream.close() führt zu mehr Ressourcenverbrauch?
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)
ich es unter Windows laufen, vor dem Start der Test, den ich für die netstat Liste warten wieder normal zu sein. Fragen
:
- warum ruft socketInputStream.close() auf der Client-Seite Harms in diesem Fall?
- oder was ist falsch mit dem Code?
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();
}
}
Sicher, dass Sie nicht diese von hinten nach vorne haben? – EJP
Können Sie weitere Informationen zu Windows-Version, Plattform 32 oder 64 Bit und Java-Version bereitstellen? – sibnick
Als Referenz habe ich Ihren Test auf Ubuntu 15.04 durchgeführt. Es hat alle Millionen Iterationen ohne Fehler abgeschlossen. Im Zustand TIME_WAIT gab es zu jedem Zeitpunkt während der Ausführung ungefähr 28000 Sockets. (Dies ist aufgrund der Geschwindigkeit der Ausführung und das Öffnen neuer Sockets) – dsh