UNIX 网络编程 chapter 7 (useless)

7.5.11 SO_REUSEADDR & SO_REUSEPORT

SO_REUSEADDR

做用1
  当没有设置SO_REUSEADDR的时候,socketA先绑定到0.0.0.0:21,而后socketB绑定到192.168.0.1:21的时候将会失败(EADDRINUSE错误),由于0.0.0.0意味着"任意本地IP地址”,也就是"全部本地IP地址“,所以包括192.168.0.1在内的全部IP地址都被认为是已经使用了。可是在设置SO_REUSEADDR以后socketB的绑定将会成功,由于0.0.0.0和192.168.0.1事实上不是同一个IP地址,一个是表明全部地址的通配地址,另外一个是一个具体的地址。注意上面的表述对于socketA和socketB的绑定顺序是无关的,没有设置SO_REUSEADDR,它们将失败,设置了SO_REUSEADDR,它将成功。服务器

做用2
  将服务器关闭后,实际上关闭了服务器的监听套接字(close),若是此时用户点击开启服务器,那么用户但愿的状况是服务器又当即启动了。因为close后,执行了主动关闭,执行主动关闭的一端,在客户执行被动关闭以后会经历TIME_WAIT状态,如上图。TIME_WAIT的时间为1-4分钟不等,当某端口处于TIME_WAIT状态时,是没法被绑定的(bind).若是在项目中用户关闭服务器后,但愿当即启动,而程序却要等1-4分钟不等的时间后才能从新启动服务器明显不是咱们所但愿的。SO_REUSEADDR套接字选项就能够用来解决这个问题,实现瞬间重启服务器.
注意
  SO_REUSEADDR须要在每次socket和bind前调用,“每次”也就是说,不能再想要重用的那一次,对经过socket新获取的套接字启用,例如socket->bind->close进入TIME_WAIT,而此时想要在TIME_WAIT状态下绑定,那么接下来sock->setsockopt->bind,bind是不会成功的,或者只觉得绑定的是同一个地址,就只第一次启用一次,也是不行的。即便是第一次得到的套接字不须要重用,也要启用该选项,这样后面每次启用才会达到预期效果。socket

SO_REUSEPORT

  SO_REUSEPORT的含义与绝大部分人对SO_REUSEADDR的理解同样。基本上说来,SO_REUSEPORT容许你将多个socket绑定到相同的地址和端口, 只要它们在绑定以前都设置了SO_REUSEPORT。若是第一个绑定某个地址和端口的socket没有设置SO_REUSEPORT,那么其余的socket不管有没有设置SO_REUSEPORT都没法绑定到该地址和端口直到第一个socket释放了绑定。
  SO_REUSEPORT并不表示SO_REUSEADDR。这意味着若是一个socket在绑定时没有设置SO_REUSEPORT,那么同预期的同样,其它的socket对相同地址和端口的绑定会失败,可是若是绑定相同地址和端口的socket正处在TIME_WAIT状态,新的绑定也会失败。当有个socket绑定后处在TIME_WAIT状态(释放时)时,为了使得其它socket绑定相同地址和端口可以成功,须要设置SO_REUSEADDR或者在这两个socket上都设置SO_REUSEPORT。固然,在socket上同时设置SO_REUSEPORT和SO_REUSEADDR也是可行的。code

相关文章
相关标签/搜索