Se eseguo il test JUnit di seguito SENZA la riga "inputStream.close()" (vedi sotto), è possibile elaborare più di 60000 richieste (ho quindi eliminato il processo). Con questa linea, non sono riuscito a fare più di 15000 le richieste, a causa di:Client SocketInputStream.close() porta a un maggiore consumo di risorse?
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)
ho eseguito su Windows, prima di iniziare il test aspetto l'elenco netstat di essere tornato alla normalità.
Domande:
- perché sta chiamando socketInputStream.close() sui danni lato client in questo caso?
- o cosa c'è di sbagliato nel codice?
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();
}
}
Certo non si dispone di questo nuovo alla parte anteriore? – EJP
È possibile fornire ulteriori informazioni sulla versione di Windows, sulla piattaforma 32 o 64 bit e sulla versione java? – sibnick
Solo per riferimento, ho eseguito il test su Ubuntu 15.04. Ha completato tutti i milioni di iterazioni senza errori. Circa 28000 socket esistevano nello stato TIME_WAIT in qualsiasi momento durante l'esecuzione. (questo è dovuto alla velocità di esecuzione e all'apertura di nuove prese) – dsh