java.net.BindException 处理

本文通过分析ServerSocket的创建及监听过程,解决了由于频繁新建ServerSocket实例而导致的端口冲突问题,并介绍了如何利用setReuseAddress方法避免端口冲突。
07-15 19:59:00.011: W/System.err(2334): java.net.BindException: bind failed: EADDRINUSE (Address already in use)
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




  




    




    




    




    




    



  
                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值