
从零构建通讯器--5.3TCP状态转换,TIME_WAIT详解,SO_REUSEADDR
发布日期:2021-05-04 18:23:28
浏览次数:17
分类:技术文章
本文共 2242 字,大约阅读时间需要 7 分钟。
(1)TCP状态转换
(1.1)结论:相同IP地址的相同端口,只能被bind一次;第二次bind会失败;
(1.2)介绍命令netstat:显示网络相关信息
-a:显示所有选项 -n:能显示成数字的内容全部显示成数字 -p:显示段落这对应程序名 netstat -anp | grep -E ‘State|9000’ //检测跟9000端口有关的信息(1.3)
//我们用两个客户端连接到服务器,服务器给每个客户端发送一串字符"I sent sth to client!\n",并关闭客户端; //我们用netstat观察,原来那个监听端口 一直在监听【listen】,但是当来了两个连接之后【连接到服务器的9000端口】, //虽然这两个连接被close掉了,但是产生了两条TIME_WAIT状态的信息【因为你有两个客户端连入进来】 只要客户端 连接到服务器,并且 服务器把客户端关闭,那么服务器端就会产生一条针对9000监听端口的 状态为 TIME_WAIT 的连接; //只要用netstat看到 TIME_WAIT状态的连接,那么此时, 你杀掉服务器程序再重新启动,就会启动失败,bind()函数返回失败: //bind返回的值为-1,错误码为:98,错误信息为:Address already in use–》》TIME_WAIT:涉及到TCP状态转换这个话题了,属于TCP的状态,使bing失败,返回错误
//TCP状态转换图【11种状态】 是 针对“一个TCP连接【一个socket连接】”来说的;
//客户端: CLOSED ->SYN_SENT->ESTABLISHED【连接建立,可以进行数据收发】 //服务端: CLOSED ->LISTEN->【客户端来握手】SYN_RCVD->ESTABLISHED【连接建立,可以进行数据收发】 //谁主动close连接,谁就会给对方发送一个FIN标志置位的一个数据包给对方;【服务器端发送FIN包给客户端】 //服务器主动关闭连接:ESTABLISHED->FIN_WAIT1->FIN_WAIT2->TIME_WAIT //客户端被动关闭:ESTABLISHED->CLOSE_WAIT->LAST_ACK法一(2)RST标志,违反四次挥手
法二(3)设置重用(2)TIME_WAIT状态
(2.0)连接处于TIME_WAIT状态是有时间限制的(1-4分钟之间) = 2 MSL【最长数据包生命周期】;
//引入TIME_WAIT状态【并且处于这种状态的时间为1-4分钟】 的原因: //(1)可靠的实现TCP全双工的终止 //如果服务器最后发送的ACK【应答】包因为某种原因丢失了,那么客户端一定 会重新发送FIN,这样 //因为服务器端有TIME_WAIT的存在,服务器会重新发送ACK包给客户端,但是如果没有TIME_WAIT这个状态,那么 //无论客户端是否收到ACK包,服务器都已经关闭连接了,此时客户端重新发送FIN,服务器给回的就不是ACK包, //而是RST【连接复位】包,从而使客户端没有完成正常的4次挥手,不友好,而且有可能造成数据包丢失; //也就是说,TIME_WAIT有助于可靠的实现TCP全双工连接的终止; (2)允许老的重复的TCP数据包在网络中消逝;(2.1)RST标志
①正常关闭://对于每一个TCP连接,操作系统是要开辟出来一个收缓冲区,和一个发送缓冲区 来处理数据的收和发; //当我们close一个TCP连接时,如果我们这个发送缓冲区有数据,那么操作系统会很优雅的把发送缓冲区里的数据发送完毕,然后再发fin包表示连接关闭; //FIN【四次挥手】,是个优雅的关闭标志,表示正常的TCP连接关闭;②粗暴关闭://反观RST标志:出现这个标志的包一般都表示 异常关闭;如果发生了异常,一般都会导致丢失一些数据包;
//如果将来用setsockopt(SO_LINGER)选项要是开启;发送的就是RST包,此时发送缓冲区的数据会被丢弃; //RST是异常关闭,是粗暴关闭,不是正常的四次挥手关闭,所以如果你这么关闭tcp连接,那么主动关闭一方也不会进入TIME_WAIT;(3)SO_REUSEADDR选项
setsockopt(SO_REUSEADDR)用在服务器端,socket()创建之后,bind()之前
/SO_REUSEADDR的能力: //(1)SO_REUSEADDR允许启动一个监听服务器并捆绑其端口,即使以前建立的将端口用作他们的本地端口的连接仍旧存在; //【即便TIME_WAIT状态存在,服务器bind()也能成功】 //(2)允许同一个端口上启动同一个服务器的多个实例,只要每个实例捆绑一个不同的本地IP地址即可; //(3)SO_REUSEADDR允许单个进程捆绑同一个端口到多个套接字,只要每次捆绑指定不同的本地IP地址即可; //(4)SO_REUSEADDR允许完全重复的绑定:当一个IP地址和端口已经绑定到某个套接字上时,如果传输协议支持, //同样的IP地址和端口还可以绑定到另一个套接字上;一般来说本特性仅支持UDP套接字[TCP不行];(3.1)两个进程,绑定同一个端口和IP:bind()失败[一个班级不能有两个人叫张三]
TCP会失败,UDP会成功 (3.2)TIME_WAIT状态时的bind绑定:bind()成功发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2025年04月03日 15时06分07秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
云计算-大数据-云安全高等教育改革示范教材
2019-03-01
Web站点安全监控
2019-03-01
使用MaxCompute进行数据质量核查
2019-03-01
JavaScript 自学手册(文档教程)
2019-03-01
Java语言特点与学习
2019-03-01
夜光带你走进Vue.js(三十二)擅长的领域
2019-03-01
夜光精讲 Opentcs 三大算法(十三)调度算法
2019-03-01
导入工程时出现错误
2019-03-01
BCGControlBar教程:应用向导
2019-03-01
MyEclipse教程:Web开发——部署并测试项目
2019-03-01
【更新】CLion v2018.3发布(六):VCS和插件
2019-03-01
文件服务器——src文件夹
2019-03-01
从零构建通讯器--5.2三次握手,telnet,wireshark
2019-03-01
如何判断两个浮点数是否相等?
2019-03-01
2021牛客寒假算法基础集训营3
2019-03-01
营收环比增幅近50%,星巴克在经历“劫”后重生吗?
2019-03-01
苹果进军搜索,背后藏着什么“阳谋”?
2019-03-01