SO_REUSEADDR

(1)首先对于一个server服务进程来说,它的创建流程是

socket->bind ->listen->accept

创建监听套接字,bind一个指定端口,listen监听端口,为每个连接提供服务(一般会创建子进程)。当服务进程重启时,那么会重新执行一遍上面的流程,如果在创建socket后没有使用SO_REUSEADDR选项进行设置,再次进行bind就会失败。那么原因是什么?
首先需要了解一下TCP协议的4次挥手动作,如文章开头的图片所示,当一个连接在关闭时,会有4次挥手的过程,TIME_WAIT状态存在于关闭发起方发送完最后一个ACK,之所以需要有一个等待时间,是为了以防最后一个ACK丢包。如果最后一个ACK丢包了会导致接收方再次重发一个FIN包,如果发起方此时还在等待,那么将还有正常处理的机会。

正常关闭
主动close socket的一方再发送最后一个ACK后会进入TIME_WAIT,默认情况下,处于TIME_WAIT状态的端口是不能用来listen的。对于服务端listen socket来说,如果在执行close时,等待队列中没有对应的连接,那么状态会直接进入closed,此时再次使用bind操作时理论上是不会有异常的,但是当我们关闭listen socket时,如果不够幸运,等待队列中还有等待处理的连接,那么后续将执行TCP的正常关闭流程,并且服务端作为发起方,那么无疑最后是会进入到TIME_WAIT状态,并且等待一定时间确保接收方已经接收了最后的一个ACK。实际上对于应用来说,执行完close它就已经退出了,而TCP的关闭流程是由内核协议栈管理的,在这个TIME_WAIT的过程中,内核是不允许再次对该地址和端口进行bind的。
异常关闭
如果是异常kill掉进程,对于server端连接状态会直接变为TIME_WAIT,如果是client端异常关闭,那么会导致server端口状态在多个状态上都需要进行等待。因此除非我们显式的指定了SO_REUSEADDR,否则我们都无法在立即重启服务后执行bind操作。

以上这就是SO_REUSEADDR对于服务端来说存在的意义。

(2)对于client进程来说,创建套接字去连接某个监听套接口,一般操作为:

socket->connect

在连接到某个服务器端口上时,我们不用执行bind操作,内核会随机为客户端生成对应的本地地址和端口号。因此这个选项使用到的机会并不会很大,加入我们没有对socket执行该选项,那么主动关闭后,虽然处于TIME_WAIT状态,但是下次执行客户端区连接时,内核会重新为客户端随机产生其他的端口号去连接,所以大多数情况下是用不到的,除非我们想要在客户端也bind端口号。

杀死进程,保证client端执行主动关闭。那么重启进程后,除非上一个连接退出了TIME_WAIT状态,否则重启的进程在调用connect时候错误返回。
主动close socket的一方再发送最后一个ACK后会进入TIME_WAIT,默认情况下,处于TIME_WAIT状态的端口是不能用来LISTEN的。会遇到的问题处于TIME_WAIT的数量过多导致后续无法连接,可以通过tcp_max_syn_backlog修改等待队列长度(这个值包括了ESTABLISHED连接和半连接),还可以用tcp_max_tw_buckets配置项来清除处于TIME_WAIT的连接。
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,(const void *)&reuse , sizeof(int));

SO_REUSEPORT

对于服务器来说默认情况下一个PORT只能被一个服务进程所占用,那么为了增加服务的能力,可以使能该特性,让多个服务进程同时复用同一个端口,提升服务吞吐量。使能该选项可以让多进程或者多线程创建多个socket绑定到同一个PORT上,提高服务器的并发能力。该特性在kernel 3.9 中引入的,因此在旧版本的内核版本上不能会用。


https://hea-www.harvard.edu/~fine/Tech/addrinuse.html

socket中的reuse addr和reuse port相关推荐

  1. socket中的TCP编程(调用免费聊天的机器人实现自动回复)

    socket中的TCP编程(调用免费聊天的机器人实现自动回复) 在无聊时间复习了socket编程,写了这个简易代码!!注意要在联网状态下跑 1:服务器模块: import socket import ...

  2. 传输层中UDP的深入理解以及socket中UDP的使用

    目录 一.学习UDP的预备知识 1.熟悉网络通信中的五元组 (1)源IP地址和目的IP地址 (2)源端口号和目的端口号 (3)协议号 2.什么是客户端和服务端 二.socketAPI中UDP的使用 1 ...

  3. Variable W already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE……

    Variable W already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarS ...

  4. Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)

    为了方便讲解,我们把 DataOutputstream dout = new DataOutputStream(new BufferedOutputStream(mySocket.getOutputS ...

  5. PYTHON__关于Socket中的Select使用理解

    关于Socket中的Select使用理解 以下是代码和中文注释的个人理解 import socket, select, Queueserver=('192.168.2.100',10086)#创建TC ...

  6. backlog配置_详解socket中的backlog 参数

    backlog: an accumulation of uncompleted work or matters needing to be dealt with. (累计未完成的待处理事件) sock ...

  7. 简单分析一下socket中的bind

    在最开始接触bind的时候,只是在写基于tcp的server端的时候,知道在listen之前需要先bind一下,用来确保socket能在某个固定的端口监听.而bind的时候,函数参数中的端口填自己将要 ...

  8. linux socket默认超时时间设置,Socket中如何设置连接超时 (转)

    Socket中如何设置连接超时 (转) Socket中如何设置连接超时 AntGhazi/2001.12.14 主页:antghazi.yeah 把CSDN与中文翻了底朝天,也没找到如何设置socke ...

  9. Socket中如何设置连接超时

    Socket中如何设置连接超时 (antghazi发表于2003-3-16 9:28:38) 设置connect的超时很简单,CSDN上也有人提到过使用select,但却没有一个令人满意与完整的答案. ...

最新文章

  1. 高效程序员的 7 个共同特征
  2. R pdf大小_怎样给PDF添加批注并同步到手机里?
  3. php上传图片到非项目目录,前端页面的读取问题
  4. rrdtutorial
  5. SAP Spartacus里的routerLink测试
  6. Calypso - Android和Evolution下的CalDAV/CardDAV/Web...
  7. 开发 Windows 8 Bing地图应用(4)
  8. python全套 百度云-2018年6月北京黑马python24期全套视频课程
  9. Aho-Corasick automaton(AC自动机)解析及其在算法竞赛中的典型应用举例
  10. 逻辑面试题:猴子搬香蕉
  11. bat——批量删除文件文件夹
  12. 兔子数列规律怎么讲_神奇兔子数列
  13. alice 和 bob 一起 van♂卡牌游戏
  14. BPM端到端流程解决方案分享
  15. Neon intrinsics
  16. (C++)GDAL学习笔记—— 5 全色影像与多光谱影像的融合
  17. cad快看_苹果用户福音——CAD快速看图mac版来啦
  18. re文件管理免root中文版,re管理器免root版本
  19. 新浪导航(html+css)
  20. 用python实现在一组数据中,寻找到最大数和最小数并输出最大数和最小数所在的位置

热门文章

  1. 学vue前你需要知道的:vue生态圈
  2. CNN网络实现手写数字(MNIST)识别 代码分析
  3. android手机华为p10,华为P10的手机系统是什么
  4. IO流 | IO流的应用举例
  5. 电脑端浏览器调试移动端网页 支持调试Android和ios
  6. FFmpeg av_frame_free崩溃可能原因
  7. java实现多元线性回归
  8. with open()as filename
  9. 单片机——点阵2(Proteus和KeilC51)
  10. h5+ 调用本地摄像头拍照