bind为什么会出现地址重用



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 ) ); 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值