07-15 19:59:00.015: W/System.err(2334): at libcore.io.IoBridge.bind(IoBridge.java:89)
07-15 19:59:00.019: W/System.err(2334): at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:150)
07-15 19:59:00.019: W/System.err(2334): at java.net.ServerSocket.<init>(ServerSocket.java:100)
07-15 19:59:00.019: W/System.err(2334): at java.net.ServerSocket.<init>(ServerSocket.java:69)
07-15 19:59:00.019: W/System.err(2334): at com.casit.controlapp.service.ControlService$TcpReceiveThread.run(ControlService.java:96)
07-15 19:59:00.023: W/System.err(2334): at java.lang.Thread.run(Thread.java:856)
07-15 19:59:00.027: W/System.err(2334): Caused by: java.net.BindException: bind failed: EADDRINUSE (Address already in use)
07-15 19:59:00.027: W/System.err(2334): at libcore.io.IoBridge.bind(IoBridge.java:89)
07-15 19:59:00.027: W/System.err(2334): at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:150)
07-15 19:59:00.027: W/System.err(2334): at java.net.ServerSocket.<init>(ServerSocket.java:100)
07-15 19:59:00.027: W/System.err(2334): at java.net.ServerSocket.<init>(ServerSocket.java:69)
07-15 19:59:00.027: W/System.err(2334): at com.casit.controlapp.service.ControlService$TcpReceiveThread.run(ControlService.java:96)
07-15 19:59:00.027: W/System.err(2334): at java.lang.Thread.run(Thread.java:856)
07-15 19:59:00.027: W/System.err(2334): Caused by: libcore.io.ErrnoException: bind failed: EADDRINUSE (Address already in use)
07-15 19:59:00.027: W/System.err(2334): at libcore.io.Posix.bind(Native Method)
07-15 19:59:00.027: W/System.err(2334): at libcore.io.ForwardingOs.bind(ForwardingOs.java:39)
07-15 19:59:00.027: W/System.err(2334): at libcore.io.IoBridge.bind(IoBridge.java:87)
07-15 19:59:00.027: W/System.err(2334): ... 5 more
07-15 19:59:00.031: W/System.err(2334): libcore.io.ErrnoException: bind failed: EADDRINUSE (Address already in use)
07-15 19:59:00.031: W/System.err(2334): at libcore.io.Posix.bind(Native Method)
07-15 19:59:00.031: W/System.err(2334): at libcore.io.ForwardingOs.bind(ForwardingOs.java:39)
07-15 19:59:00.031: W/System.err(2334): at libcore.io.IoBridge.bind(IoBridge.java:87)
07-15 19:59:00.035: W/System.err(2334): ... 5 more
在编写socket通信时出现了上述的log信息,在log信息中的两端蓝色字体中,强调了 java.net.BindException的异常,原因bind failed: EADDRINUSE (Address already in use)
查找资料,在《Unix-网络编程 卷1:套接字联网API》一书中有对 TIME_WAIT状态,bind()函数的讲解,再联系我当时写的程序:
ServerSocket stopServerSocket;
Socket stopSocket;
while(true){
try{
stopServerSocket = new ServerSocket(45000);
stopSocket = stopServerSocket.accept();
}catch(IOException e){
e.printStackTrace();
}
}
我在server端不停建立new新的ServerSocket,这就导致了地址冲突。
我仔细一分析,发现我写的代码有问题,我需要做的是在服务器的45000端口监听socket,而并不需要每次都new一个新的ServerSocket,于是我将代码改为如下:
ServerSocket stopServerSocket;
Socket stopSocket;
topServerSocket = new ServerSocket(45000);
while(true){
try{
stopSocket =stopServerSocket.accept();
}catch(IOException e){
e.printStackTrace();
}}
在修改之后,程序运行没有问题,但是我在看了一些资料后在原来的程序中加入了:
setReuseAddress(boolean on)方法
Enable/disable the SO_REUSEADDR socketoption.
这个方法主要是使能SO_REUSEADDR,对于这个变量的解释在 http://developerweb.net/viewtopic.php?id=3019,代码如下:
while(true){
try {
if(stopServerSocket == null){
stopServerSocket = new ServerSocket();
stopServerSocket.setReuseAddress(true);
stopServerSocket.bind(newInetSocketAddress(40000));
}
stopSocket= stopServerSocket.accept();
}catch(IOException e){
e.printStackTrace();
}
上面的方法中,相当于就是我建立许多的ServerSocket,但是它们都是使用同一个45000端口,因为有setReuseAddress(true)这个方法就是的同一个端口可以被多个socket使用,不会出现 (Address already in use)的问题
更多的资料可以参考:http://blog.youkuaiyun.com/liusujian02/article/details/1944520
http://www.360doc.com/content/11/0820/09/4602013_141864815.shtml
本文通过分析ServerSocket的创建及监听过程,解决了由于频繁新建ServerSocket实例而导致的端口冲突问题,并介绍了如何利用setReuseAddress方法避免端口冲突。
1726

被折叠的 条评论
为什么被折叠?



