windows中socket 连结绑定数过多问题

04-11-16 mingming10
程序功能:

调用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多个就出现错误了。

问题:

如何强制让系统把这些端口快速释放?

或者怎样让默认使用的绑定端口数增加?

banq
2004-11-20 22:21
有意义的测试,虽然不能帮忙,顶一下。

mingming10
2004-11-22 15:56
最后也没找到解决办法,只好在配置文件里面限定只发送3800次.

从目前的数据看,java直接访问 和调用jni访问速度差不多!!

也许是因为服务端需要处理数据,处理时间抵消了两者的实际差距。

scoop
2004-11-23 09:18
按照TCP协议的规定,socket连接关闭后会进入time_wait状态,缺省设置下4分钟后会被回收。该时间可由以下参数设置:

tcp_time_wait_interval

猜你喜欢