bind为什么会出现地址重用

    xiaoxiao2021-03-25  52

    

    1、在客户端服务器模式中,如果服务器退出,然后立即重新启动的话,然后就出现”试图绑定一个已经在使用的端口”的错误,要等过一段时间之后才可以bind,这是为什么呢??? 或许你感到非常迷惑,明明服务器的套接字已经被关闭了,但为什么仍然禁止绑定端口。这是由于套接字处于TIME_WAIT状态引起的,这个状态会持续2MSL时间。在TIME_WAIT退出后,套接字被删除,该地址才能被重新绑定而不出现问题。 如图:

    2、等待TIME_WAIT真的让人很不爽,可以采用下面这种方式避免TIME_WAIT状态。 在bind之前,用SO_REUSEADDR选项调用setsockopt函数。

    int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); 1 1

    功能:用于在任意类型、任意状态的套接字上设置选项值。选项影响套接字的操作。 参数: sockfd:套接字的描述符。 level:选项定义的层次。

    SOL_SOCKET: 基本套接口 IPPROTO_IP: IPv4套接口 IPPROTO_IPV6: IPv6套接口 IPPROTO_TCP: TCP套接口

    optname:设置的选项。 optval:指向选项类型的指针。选项有两种类型的 ,一种是布尔类型的选项,表示允许(TRUE)或禁止(FALSE)一种特性。另一种整形选项,非零表示允许,零表示禁止。 optlen:optval缓冲区去的大小。 返回值:若无错误发生,则返回0。

      选项 类型 意义   SO_BROADCAST BOOL 允许套接口传送广播信息。   SO_DEBUG BOOL 记录调试信息。   SO_DONTLINER BOOL 不要因为数据未发送就阻塞关闭操作。设置本选项相当于将SO_LINGER的l_onoff元素置为零。   SO_DONTROUTE BOOL 禁止选径;直接传送。   SO_KEEPALIVE BOOL 发送“保持活动”包。   SO_LINGER struct linger FAR* 如关闭时有未发送数据,则逗留。   SO_OOBINLINE BOOL 在常规数据流中接收带外数据。   SO_RCVBUF int 为接收确定缓冲区大小。   SO_REUSEADDR BOOL 允许套接口和一个已在使用中的地址捆绑(参见bind())。   SO_SNDBUF int 指定发送缓冲区大小。 TCP_NODELAY BOOL 禁止发送合并的Nagle算法。 setsockopt()不支持的BSD选项有:

      选项名 类型 意义   SO_ACCEPTCONN BOOL 套接口在监听。   SO_ERROR int 获取错误状态并清除。   SO_RCVLOWAT int 接收低级水印。   SO_RCVTIMEO int 接收超时。   SO_SNDLOWAT int 发送低级水印。   SO_SNDTIMEO int 发送超时。   SO_TYPE int 套接口类型。   IP_OPTIONS 在IP头中设置选项。

    用法示例:

    1.设置调用closesocket()后,仍可继续重用该socket。调用closesocket()一般不会立即关闭socket,而经历TIME_WAIT的过程。   BOOL bReuseaddr = TRUE;   setsockopt( s, SOL_SOCKET, SO_REUSEADDR, ( const char* )&bReuseaddr, sizeof( BOOL ) ); 2.在send(),recv()过程中有时由于网络状况等原因,收发不能预期进行,可以设置收发时限:   int nNetTimeout = 1000; //1秒   //发送时限   setsockopt( socket, SOL_SOCKET, SO_SNDTIMEO, ( char * )&nNetTimeout, sizeof( int ) );   //接收时限   setsockopt( socket, SOL_SOCKET, SO_RCVTIMEO, ( char * )&nNetTimeout, sizeof( int ) );

    转载请注明原文地址: https://ju.6miu.com/read-37165.html

    最新回复(0)