《关闭服务器,再次启动服务器提示bind:address already in use》

  首先,我们先声明:bind:address already in use的存在是合理的,在服务端终止之后,会有一个TIME_WAIT的状态,再次打开会出现:bind:address already in use。

  但是,当我们等上个2-4分钟后,然后在运行,就又没有这种情况了,很好解释,那只是因为在一定的时间内这个端口还被占用着,没有来的及释放,但是2-4分钟后,端口释放完毕,所以可以正常的运行这个程序了

  服务器端可以尽可能的使用REUSEADDR(在绑定之前尽可能调用setsockopt来设置REUSEADDR)套接字选项,这样就可以使得不必等待TIME_WAIT状态就可以重启服务器了,也就是说:TIME_WAIT状态还是存在的,但是不影响我们重新启动服务器。

  TIME_WAIT:我方主动调用close()断开连接,收到对方确认后状态变为TIME_WAIT。TCP协议规定TIME_WAIT状态会一直持续2MSL(即两倍的分 段最大生存期),以此来确保旧的连接状态不会对新连接产生影响。处于TIME_WAIT状态的连接占用的资源不会被内核释放,所以作为服务器,在可能的情 况下,尽量不要主动断开连接,以减少TIME_WAIT状态造成的资源浪费。目前有一种避免TIME_WAIT资源浪费的方法,就是关闭socket的LINGER选项。但这种做法是TCP协议不推荐使用的,在某些情况下这个操作可能会带来错误。

  解决方案:

  1.软件编程的时候避免这个问题

  当我们用:setsockopt和SO_REUSEADDR时:充分的减少了等待时间,在一次的通讯完毕,可以直接再次的运行这个程序,这样就不会出现上面如:bind:address already in use。

//调高端口的重用性
int on;
if(setsockopt(g_ptSerContext->iServerFd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(int))<<0)
{
     perror("setsockopt error\n");
     return 0;
}
if(bind(g_ptSerContext->iServerFd,(struct sockaddr *)&g_ptSerContext->SockAdd,\
 sizeof(g_ptSerContext->SockAdd))==-1)
{
        perror("bind error\n");
        return 0;

   2.通过kill来直接关闭端口

  netstat -apn | grep 2181(这里的端口号,替换成你被占用的那个端口号,比如Tomcat是8080,namenode是8020之类的,还有最好用root来使用这些系统级的命令)

  然后得到这样的结果:

  

 

   最后一排其实就pid,然后我们通过kill -9 pid 就可以杀掉对应的进程(例如,kill -9 4438)

  但是kill前,我们还是要确定下到底这个哪里开的进程能不能随便杀掉,所以。。。

  ps -ef | grep 4438

 

   这边显示了两行,每行都是以用户名开头的,第一个就是普通用户开启的namenode进程,第二个是root用户执行的ps -ef | grep 4438这个命令生成的,就好像我们每次jps的时候,就有jps这个进程。

  最后一步其实就是kill -9强制杀掉。

     

 

 

 

 

 

  

posted @ 2019-12-14 15:26  一个不知道干嘛的小萌新  阅读(1258)  评论(0编辑  收藏  举报