发帖    主题    评论    推荐    标签    作者    订阅    查搜    注册   登陆   关注
 
面向对象 设计模式 领域驱动设计 企业架构 框架 开发教程 微服务 CQRS 扩展性 并发编程 事件溯源 分布式 SOA

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

2004-11-16 16:02
赞助商链接

程序功能:
调用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多个就出现错误了。

问题:
如何强制让系统把这些端口快速释放?
或者怎样让默认使用的绑定端口数增加?

2004-11-20 22:21

有意义的测试,虽然不能帮忙,顶一下。

2004-11-22 15:56

最后也没找到解决办法,只好在配置文件里面限定只发送3800次.
从目前的数据看,java直接访问 和调用jni访问速度差不多!!
也许是因为服务端需要处理数据,处理时间抵消了两者的实际差距。

2004-11-23 09:18

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

tcp_time_wait_interval

赞助商链接

赞助商链接

返回顶部

移动版 关于本站 使用帮助 联系反馈 最佳分辨率1366x768
OpenSource JIVEJDON Powered by JdonFramework Code © 2002-20 jdon.com