windows中socket 連結繫結數過多問題
程式功能:
呼叫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多個就出現錯誤了。
問題:
如何強制讓系統把這些埠快速釋放?
或者怎樣讓預設使用的繫結埠數增加?
呼叫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多個就出現錯誤了。
問題:
如何強制讓系統把這些埠快速釋放?
或者怎樣讓預設使用的繫結埠數增加?
相關文章
- ORACLE未繫結變數和硬解析過多問題處理Oracle變數
- Laravel 框架中 whereRaw like 引數繫結問題Laravel框架
- 【優化】使用繫結變數 OR 不使用繫結變數,這不是問題!優化變數
- 管中窺豹-ssh連結過多的問題分析及覆盤
- 【最佳化】使用繫結變數 OR 不使用繫結變數,這不是問題!變數
- Windows Socket 最大連線數Windows
- SpringMVC中的引數繫結總結SpringMVC
- Grails中如何繫結引數AI
- (連結串列)連結串列的排序問題排序
- jquery中事件重複繫結以及解綁問題jQuery事件
- Windows下單網路卡繫結多個IP地址Windows
- vue中v-on繫結多個方法Vue
- vue中select繫結多個值Vue
- 繫結變數變數
- orbis 連結 .a的問題ORB
- Mysql 左連結問題MySql
- 連結串列專題——面試中常見的連結串列問題面試
- Windows中改變網路卡繫結順序Windows
- 用Oracle表函式解決繫結變數集合問題Oracle函式變數
- 關於DSS中的繫結變數變數
- jQuery事件中on實現繫結多個事件jQuery事件
- IOC容器的繫結解析過程(繫結單例)單例
- 繫結變數之繫結變數窺探(Bind Peeking)變數
- Laravel 多鍵路由繫結Laravel路由
- Oracle 繫結變數Oracle變數
- ORACLE 繫結變數用法總結Oracle變數
- 環形連結串列_相交連結串列_多數元素(java語言)Java
- 約瑟夫環(Josephus)問題--報數遊戲(連結串列)遊戲
- 靜態連結動態連結的連結順序問題和makefile示例
- 【YashanDB知識庫】繫結引數,同一個sql多個執行計劃的問題SQL
- Oracle資料傾斜導致的問題-有繫結變數Oracle變數
- Oracle資料傾斜導致的問題-無繫結變數Oracle變數
- gridview中帶多引數超連結的實現View
- Windows 中的硬連結、目錄聯接(軟連結)、符號連結、快捷方式Windows符號
- WPF TreeView IsExpanded 繫結不上的問題View
- 關於pl/sql中的繫結變數SQL變數
- OCI中繫結變數的實現例子變數
- 資料結構連結串列各種問題資料結構