• socket关闭


    首先应该了解win32 api closesocket,这里只说msdn文档中叙述不够清晰的地方。

    首先说缺省情况:l_onoff为0,closesocket立刻返回,但底层依然在持续发包,并且试图优雅关闭连接。这种情况下对于应用程序来说,该连接已经关闭,但底层socket的相关资源还没有释放,且不知道要等待多长时间。该方法对于一般程序来说没有问题,对于服务器来说,因为有可能有非常多的socket(超过100k),这样处理可能会导致系统可用的socket资源不足。

    其次说l_onoff不为0的情况,此时取决于l_linger的值,系统会尽可能的优雅的关闭连接,如果在l_linger的时间内还无法关闭连接,则硬关闭。也就是说,此时如果l_linger为0,则肯定硬关闭,且closesocket立刻返回,同时释放所有资源。如果l_linger不为0,则尽可能优雅关闭并返回,释放所有资源,如果超时,则硬关闭,closesocket返回,释放所有资源。注意此种情况下closesocket可能是同步的。

    shutdown有2个作用。首先禁止后续的send或者recv,但注意它不会影响底层,也就是说,此前发出的异步send/recv不会返回。其次,在所有发送的包被对方确认后,会发送FIN包给对方,试图优雅的关闭连接。但shutdown本身并不影响任何底层的东西,因此,shutdown并且优雅关闭了连接之后,该socket以及其所关联的资源依然存在,必须调用closesocket才能释放。

    1.重用端口
    假如服务器关闭或者退出,造成本地地址和端口都处于TIME_WAIT状态,那么SO_REUSEADDR就显得非常有用

    int nREUSEADDR = 1;
    
    setsockopt(sockConnected,
    
                  SOL_SOCKET,
    
                  SO_REUSEADDR,
    
                  (const char*)&nREUSEADDR,
    
                  sizeof(int));
    

    2.强制关闭连接

    在connect成功建立连接之后设置该选项:
    
    linger m_sLinger;
    
    m_sLinger.l_onoff = 1;  // (在closesocket()调用,但是还有数据没发送完毕的时候容许逗留)
    
    m_sLinger.l_linger = 0; // (容许逗留的时间为0秒)
    
    setsockopt(sockConnected,
    
             SOL_SOCKET,
    
             SO_LINGER,
    
             (const char*)&m_sLinger,
    
             sizeof(linger));
    

    设置SO_LINGER为零(亦即linger结构中的l_onoff域设为非零,但l_linger为0),便不用担心closesocket调 用进入“锁定”状态(等待完成),不论是否有排队数据未发送或未被确认。这种关闭方式称为“强行关闭”,因为套接字的虚电路立即被复位,尚未发出的所有数 据都会丢失。在远端的recv()调用都会失败,并返回WSAECONNRESET错误。

  • 相关阅读:
    小涛涛的计算器
    Sort排序浅聊
    程序员PC选购
    冒泡排序
    Django之模板
    Django中model的Meta选项
    Django之路由系统
    Django之视图系统
    踏上Flask的不归路(二)
    踏上Flask的不归路(一)
  • 原文地址:https://www.cnblogs.com/ggzone/p/5094529.html
Copyright © 2020-2023  润新知