• 《关闭服务器,再次启动服务器提示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
    ");
         return 0;
    }
    if(bind(g_ptSerContext->iServerFd,(struct sockaddr *)&g_ptSerContext->SockAdd,
     sizeof(g_ptSerContext->SockAdd))==-1)
    {
            perror("bind error
    ");
            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强制杀掉。

         

      

  • 相关阅读:
    【个人笔记】MySQL聚合函数、子查询
    artTemplate的使用总结
    【学习笔记】node.js入门基础
    【知了堂学习笔记】SQL查询基础语句(单表查询、多表查询)
    浅谈java final关键字
    3D魔幻旋转
    3分钟实现星空图
    深入浅出,谈谈面向对象几大特征
    html,css常用标签
    java中常用集合的理解
  • 原文地址:https://www.cnblogs.com/zhuangquan/p/12039687.html
Copyright © 2020-2023  润新知