windows中socket 連結繫結數過多問題

mingming10發表於2004-11-16
程式功能:
呼叫socket與服務端連線1萬次,分別用java直接呼叫和用jni呼叫
目的在於測試jni與java的速度差距。

主要程式碼如下
for (int i = 0; i < 100000; i++) {
if (type.equalsIgnoreCase("jni")) {
jniClient.SendFile(filename);
} else if (type.equalsIgnoreCase("java")){
sendData(filename);
} else {
throw new Exception("not support type :" + type);
}

logger.debug(String.valueOf(i));
if (sleepInterval > 0) {
Thread.sleep(sleepInterval);
}
}


//傳送函式
private void sendData(String filename) throws Exception {
Socket socket = null;
OutputStream out = null;
InputStream in = null;

try {
// 接到指定的主機和埠
socket = new Socket(host, port);

// 接到列印流
out = socket.getOutputStream();

// read from file.
in = new FileInputStream(filename);
byte[] bRead = new byte[1024 * this.catcheSize];
int iRead = 0;

out.write(0x00); // begin flag.
// write length
if (this.writeFileLength) {
long contentLength = new File(filename).length();
byte[] m_byteContLenBuf = new byte[4];
m_byteContLenBuf[0] = (byte) ( (contentLength >> 24));
m_byteContLenBuf[1] = (byte) ( (contentLength >> 16) & 0xff);
m_byteContLenBuf[2] = (byte) ( (contentLength >> 8) & 0xff);
m_byteContLenBuf[3] = (byte) (contentLength & 0xff);

//java.io.DataOutputStream dos = new DataOutputStream(out);
//dos.write(m_byteContLenBuf);
out.write(m_byteContLenBuf);
}

// write with buffer.
for(;;) {
iRead = in.read(bRead);
if (iRead < 0) break;
out.write(bRead, 0, iRead);
}
out.flush();

// wait server response
if (this.waitServerResponse) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
System.out.println("return code: " + reader.readLine());
reader.close();
}

} finally {
if (out != null) {
try {
out.close();
} catch (IOException ex) {
}
}
if (in != null) {
try {
in.close();
} catch (IOException ex1) {
}
}
if (socket != null) {
try {
socket.close();
socket = null;
} catch (IOException ex2) {
}
}

}
}


執行到4000次時,錯誤資訊如下
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at TCPClient3.sendData(TCPClient3.java:285)
at TCPClient3.testSpeed(TCPClient3.java:255)
at TCPClient3.testMuti(TCPClient3.java:207)
at TCPClient3.execute(TCPClient3.java:169)
at TCPClient3.main(TCPClient3.java:47)


出現錯誤時,用netstat -na 觀察tcp埠,發現有4000個埠處於TIME_WAIT狀態。
如下:
TCP 10.17.153.54:4996 10.17.153.55:1500 TIME_WAIT
(用jni的時候也是執行到4000次就出現連線錯誤,但c沒有列印詳細錯誤資訊)

分析:
雖然java 裡面已經關閉了socket連線,但系統出於某種考慮,繫結的埠並沒有立刻釋放。
並且預設能夠使用的埠號也並沒有6萬多個,一般到4000多個就出現錯誤了。

問題:
如何強制讓系統把這些埠快速釋放?
或者怎樣讓預設使用的繫結埠數增加?

相關文章