jquery网站开发实例,高端定制外贸网站,数据库主机wordpress,南京网站搭建公司✨感谢您阅读本篇文章#xff0c;文章内容是个人学习笔记的整理#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏#xff1a;Linux篇–CSDN博客 文章目录 TCP协议#xff08;第一部分#xff09;一.TCP协议段格式1.回… ✨感谢您阅读本篇文章文章内容是个人学习笔记的整理如果哪里有误的话还请您指正噢✨ ✨ 个人主页余辉zmh–CSDN博客 ✨ 文章所属专栏Linux篇–CSDN博客 文章目录 TCP协议第一部分一.TCP协议段格式1.回答两个问题2.窗口大小的作用3.序号和确认序号的作用4.6个标志位的作用 二.确认应答ACK机制三.超时重传机制四.连接管理机制 TCP协议第一部分
TCP全称为”传输控制协议“是一个具有接受和发送缓冲区的全双工通信的数据传输控制的一种协议。
一.TCP协议段格式
首先同一份数据在网络协议栈中的不同层次有不同的名称比如在应用层一般叫做请求和响应数据在传输层中一般叫做数据段在网络层一般叫做数据报在数据链路层一般叫做数据帧。所以同样都是二进制数据在不同层有不同的名称。
TCP协议对应的数据段格式 1.回答两个问题
1.TCP如何把数据段交付到上层应用层的
当一台主机收到一个TCP数据段时操作系统会检查数据报头中的”目的端口号“字段。这个端口号对应着本地运行的某个应用程序比如HTTP服务器的端口号为80。操作系统根据端口号把数据交给对应的应用程序。
2.TCP如何把报头和有效载荷正确分离
在报头中有一个”4位首部长度“字段这个字段占4位数字范围0~150000~1111单位是4字节32位字长度范围是0~60字节表示TCP头部的长度标准报头选项。例如如果首部长度字段的值是5表示TCP头部长度为5*420字节这是没有选项的最小长度如果首部长度的值是15表示TCP头部长度为15*460字节其中标准报头的长度是20字节选项长度是40字节。操作系统读取这个字段就知道从第几个字节开始是有效载荷数据部分从而把报头和有效载荷分开。
举例说明
首部长度字段是5即20字节那么前20字节就是TCP头部后面的就是应用层数据比如HTTP请求内容
2.窗口大小的作用
TCP报头
客户端和服务器在基于TCP协议通信时每次发送的数据包都会带有TCP报头。TCP报头中包含了如源端口号目的端口序列号窗口大小等关键信息。
流量控制
流量控制是TCP协议中的一种机制用来防止发送方发送数据过快导致接收方来不及处理最终造成数据丢失。
简单来说就是让发送方的发送速度适应接收方的接收能力。
确认应答机制
TCP是面向连接的可靠的传输协议。每当接收方收到数据后会发送一个应答包告诉发送方”我已经收到了你发来的数据“。
明白了上面的三点就能理解TCP是如何实现流量控制的 当发送方给接收方发送一个数据后根据确认应答机制接收方需要给发送方发送一个应答包因为双方是基于TCP协议通信的所以接收方发送的应答包中也包含了TCP报头其中就有一个16位窗口大小该窗口大小表示接收方当前还能接受多少字节的数据也就是接收缓冲区的剩余空间发送方收到应答包后根据报头中的窗口大小来调整自己的发送速率从而避免发送过快导致接收方的缓冲区溢出而通信是双向的所以双方在通信时都会在窗口大小字段中填写自己接收缓冲区的剩余空间大小已告知对方从而控制发送速率。 总结
1.窗口大小字段就是用来做流量控制的确保双方都不会因为对方发送过快而导致缓冲区溢出。
2.双向通信时双方都要动态的告知对方自己的接受能力这就是TCP流量控制的核心机制。
3.序号和确认序号的作用
1.TCP是面向字节流的协议
发送方把要发送的数据看作一个连续的字节流每个字节都有一个唯一的序号。发送方和接收方都以”字节“为单位进行编号和确认。
2.数据的发送方式
发送方在未收到确认的情况下连续发送多个数据包而不是”发一个等一个“提高了传输效率。发送方会为每个数据包分配一个”序号“这个序号是本包第一个字节在整个字节流中的位置。
3.数据包可能会乱序到达
由于网络原因数据包可能不是按顺序到达接收方例如先发送的包可能后到后发的包可能先到。
4.接收方根据序号重排
接收方收到数据包后会根据每个包的序号把数据重新排列保证最终交付给应用层的数据是有序的。
5.接收方发送应答包
接收方收到数据后会发送一个应答包给发送方告知”我已收到哪些数据期待下一个字节的序号是多少“。确认序号表示”下一个期望收到的自己序号“即”我已经收到你发来的所有数据知道这个序号减一为止“。
6.累计确认
TCP的应答包通常都是累计确认即”我已经连续收到从起始序号到某个序号的所有数据“。如果有数据丢失或乱序应答包会停在缺失的哪个字节序号直到缺失的数据被补齐。
7.超时重传机制
如果发送方在一定时间内没有收到某个数据的应答包会自动重传未被确认的数据包直到收到确认。只要连接没有异常断开所有的数据最终都会被确认和重传保证可靠性。
举个例子 假设发送发A接收方B A发送了序号为1000的数据包长度为599字节即1000~1499B收到后发送ACK应答包确认序号为1500表示我已经收到1000~1499期待下一个是1500如果A再发送1500~1999的数据包B收到后再发ACK应答包为2000.如果中间某个数据包丢了B的ACK会停在缺失的那个序号A没有收到ACK后会重新发送直到B收到并确认为止。 总结 序号标识每个数据包中的第一个字节在整个字节流中的位置让接收方能够识别数据包的顺序进行乱序重排。确认序号告诉发送方”我已经收到哪些数据期待下一个字节的序号是多少“让发送方知道哪些数据已经被可靠接收那些还需要重传。 两者配合共同实现了TCP的可靠有序传输 4.6个标志位的作用
先来理解什么是标志位
在基于TCP协议通信时发送的TCP报文有不同的用途比如建立连接数据传输断开连接等。可以理解为TCP报文是有”类型“的不同的类型决定了该报文不同的用途。
但TCP协议本身没有专门的“类型字段”而是通过报头中的6个标志位来区分报文的作用。
不同的标志位或他们的组合决定了报文的具体用途当接收方收到报文后通过检查这些标志位判断该报文应该如何处理。
所以标志位的存在就是为了让接收方能够区分报文的不同作用并据此做出相应的处理动作。
接下来就是详细介绍6个标志位的具体作用
1.ACK
作用
ACK标志位用于指示该报文段中的确认序号字段是否是有效的。
确认收到数据
当ACK标志位被置为1时表示该报文段携带了一个有效的确认序号用于告诉对方“我已经收到了你发来的数据到某个字节为止”为0那就是无效
保证数据可靠传输
通过ACK机制TCP实现了可靠的数据传输发送方只有在收到对方的ACK确认后才认为数据已经被可靠送达。
典型场景
建立连接三次握手中的第二次和第三次正常的数据传输接收方需要发送带ACK标志位的报文也就是应答包告知对方哪些数据已经收到断开连接四次挥手的过程中通过互相发送ACK标志位的报文确认双方的断开请求
2.SYN
作用
SYN标志位用于TCP建立连接发起和响应连接请求并同步双方的初始序号是三次握手的关键带有SYN标志位的称为同步报文段。
第一次握手
客户端发送SYN1的报文表示请求建立连接并告知自己的初始序号。
第二次握手
服务端收到后回复SYN1ACK1的报文表示同意连接并告知自己的初始序号同时确认客户端的序号。
第三次握手
客户端收到后回复ACK1的报文连接建立完成。
SYN报文的特点
SYN1时通常不携带数据只用于建立连接只有在三次握手阶段SYN标志位才会被置为1SYN报文段的序号字段用于告诉对方本端的初始序号
3.FIN
作用
FIN标志位用于TCP断开连接表示发送方已经没有数据要发送了请求关闭连接。
当一方发送带有FIN标志的报文时表示“我已经没有数据要发送了请求断开本次的连接”对方收到带有FIN标志的报文后会发送ACK进行确认并进入关闭流程完成TCP的四次挥手断开连接。
4.PSH
作用
PSH标志位用于提示接收方“立即将数据交付给应用层”而不是在缓冲区中等待更多数据。
加快数据传递速度
让接收方“马上”把数据交给应用层而不是等缓冲区满了再交付
提升实时性和交互体验
适用于对时效性要求高的应用比如聊天软件即时通讯金融交易在线游戏等确保数据能够被接收方应用层第一时间处理。
5.RST
作用
RST标志位用于TCP重新建立连接通常把携带RST标志位的报文称为“复位报文段。
应用场景分析
在客户端与服务器三次握手建立连接时当第三次握手客户端发送完ACK后客户端就认为连接已经建立可以开始发送数据了。但是如果第三次ACK在网络中丢失或者延迟服务器就会还停留在第二次握手完成阶段认为此时连接还并没有建立。这时服务器如果先收到了客户端发来的数据包不是ACK而是应用数据 服务器就会发现当前并没有与该客户端建立连接完成却受到了数据包。按照TCP协议服务器就会发送一个带有RST标志位的报文告诉客户端”连接不存在或为建立请重连“。
在这个应用场景中
客户端误以为连接已经建立提前发送数据但服务器还没准备好。服务器收到”无主“的数据包只能用RST强制告知客户端”连接无效“。
6.URG
作用
URG标志位用于表示紧急指针是否有效。
紧急指针的作用
紧急指针是TCP报头中的一个字段只有当URG标志位为1时才有效。用来指明报文中紧急数据地结束位置让接收方知道哪些数据是”紧急的“需要优先处理。
紧急指针的含义 紧急指针不是紧急数据的字节序好而是从当前序号开始往后数多少字节是紧急数据。紧急指针的值当前序号紧急数据最后一个字节的序号1。 例子 当前TCP报文的序号是1000紧急指针是5那么这表示从1000开始的5个字节1000~1004是紧急数据接收方需要优先处理这5个字节。
二.确认应答ACK机制
在讲解确认序号和ACK标志位时已经提到过确认应答机制是什么了这里就不过多讲述。 三.超时重传机制
如果主机A发送数据给主机B之后可能因为网络拥堵等原因数据无法到达主机B如果主机A在一个特定的数据间隔内没有收到哦B发来的确认应答就会进行重发 但是主机A未收到B发来的确认应答也可能是因为ACK丢失了 因此主机B会受到很多重复数据那么TCP协议需要能够识别出哪些数据包是重复的并且把重复的丢弃掉这时候就可以利用前面提到的序列号来达到去重的效果。
那么超时的时间如何确定 最理想的情况下找到一个最小的时间保证”确认应答一定能在这个时间内返回“但是这个时间的长短随着网络环境的不同是有差异的如果时间设得太长会影响整体的重传效率如果超时时间设得太短会可能频繁发送重复的包。 TCP为了保证无论在任何环境下都能比较高性能的通信因此会动态计算这个超时时间。 Linux中超时以500ms为一个单位进行控制每次判定超时重发的超时时间都是500ms的整数倍。如果重发一次后仍然得不到应答等待2*500ms后再进行重传。如果仍然得不到应答等待4*500ms进行重传以此类推以指数形式递增累积到一定的重传次数TCP认为网络或者对端主机出现异常强制关闭连接。 四.连接管理机制
在正常的情况下TCP要经过三次握手建立连接四次挥手断开连接。 服务端状态转化 CLOSED-LISTEN服务端调用listen函数后进入LISTEN状态开始监听等待客户端连接LISTEN-SYN_RCVD服务端收到客户端发送的连接请求SYN报文后就将该连接放入到内核半连接队列中SYN_RCVD-ESTABLISHED服务端一旦收到客户端的确认报文后就进入ESTABLISHED状态连接从半连接队列转移到全连接队列然后等待应用层调用accep函数从全连接队列中获取连接进行后续读写数据。ESTABLISHED-CLOSE_WAIT当客户端主动关闭连接调用close服务器返回确认报文并进入CLOSE_WAIT状态CLOSE_wAIT-LAST_ACK进入CLOSE_WAIT后说明服务器关闭连接需要处理完之前的数据当服务器真正调用close关闭连接时会向客户端发送FIN此时服务器进入LSAT_ACK状态等待最后一个ACK到来这个ACK是客户端确认收到了FINLAST_ACK-CLOSED服务器收到了对FIN的ACK彻底关闭连接。 客户端状态变化 CLOSED-SYN_SENT客户端调用connect发送同步报文段SYN_SEN-ESTABLISHED客户端收到服务器的确认和连接请求发送确认报文段connect调用成功进入ESTABLISHED状态开始读写数据ESTABLISHED-FIN_WAIT_1客户端主动调用close时向服务器发送结束报文段FIN同时进入FIN_WAIT1;FIN_WAIT_1-FIN_WAIT_2客户端收到服务器对结束报文段的确认ACK则进入FIN_WAIT_2开始等待服务器的结束报文段FIN_WAIT_2-TIME_WAIT客户端收到服务器发来的结束报文段FIN进入TIME_WAIT并发出最后一个确认报文段ACKTIME_WAIT-CLOSED客户端要等待2MSL的时间才会进入CLOSED状态。 建立连接时的细节点
建立连接三次握手是由操作系统自动完成的不依赖于应用层是否调用accept函数服务端调用listen后内核会维护一个半连接队列SYN队列和全连接队列accept队列。 半连接队列存放那些已经收到客户端SYN服务端回复了SYNACK但还没有收到客户端最后ACK的连接即服务端处于SYN_RECV状态。全连接队列存放那些三次握手已经全部成功服务端收到客户端ACK状态变为ESTABLISHED等待应用层调用accept函数从该队列中获取连接。连接建立时先进入半连接队列收到ACK后转到全连接队列。 全连接队列的长度和listen函数的第二个参数backlog有关。 backlog1指定了全连接队列的最大长度也就是最多允许存放的连接个数。如果全连接队列已满新的已完成三次握手的连接会被丢弃或拒绝客户端可能收到RST或重试。实际上最大长度可能还受操作系统内核参数限制。 连接的超时与清理 如果服务端长时间收不到客户端的ACK比如客户端网络异常恶意攻击等这个连接会一直停留在半连接队列。操作系统会有超时机制如果超时还没收到ACK内核会自动清理这个半连接释放资源防止服务端资源被无效连接占用。
经典问题1为什么全连接队列不能设置太长也不能设置太短 设置太长的后果 资源占用增加 队列太长内核需要为每个连接分配内存和管理结构会消耗更过系统资源内存CPU 延迟增加 如果应用层处理不过来连接在队列中等待时间就会变长客户端感知到相应变慢影响体验 隐藏问题 队列太长可能掩盖了应用层处理能力不足的问题导致问题积压最终可能引发更严重的故障如内存耗尽进程崩溃 被攻击风险增加 队列过长攻击者可以更容易发起SYN洪水等攻击占满队列拖垮服务器。 设置太短的后果 易导致连接丢失 如果队列太短短时间内有大量客户端同时连接队列很快就会被占满。此时新完成三次握手的连接会被丢弃或拒绝客户端可能收到RST或连接超时用于体验变差 抗突发能力差 在高并发场景下服务端无法承受瞬时的连接高峰容易出现“假死”或拒绝服务 资源利用不充分 服务器明明还有处理能力但因为队列太短连接被提前拒绝浪费了服务器资源。 最后结论全连接队列的长度不能太长也不能太短要结合实际业务和服务器能力动态调优。 断开连接时的细节点
TIME_WAIT状态的本质 TIME_WAIT状态是主动关闭连接即最后一个发送ACK的一方在完成四次挥手后进入的状态。在TIME_WATI期间该连接的IP地址和端口号四元组依然被占用不能被新的相同四元组的连接复用。TIME_WATI的持续时间通常是2倍的MSL报文在网络中的最大生存时间在Linux下默认是60秒。 服务器主动断开带来的影响 如果服务器主动关闭连接就会进入TIME_WAIT状态。在等待的期间相同的IP地址和端口号不能被立即复用这会导致服务器崩溃后立即重启绑定同样的IP和端口号会失败提示Address already in use。解决方法可以通过setsockopt函数设置套接字端口复用选项SO_REUSEADDR
int opt1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, opt, sizeof(opt));经典问题2为什么断开连接时需要TIME_WAIT状态并且时间是2倍的MSL TIME_WAIT状态的主要作用有两个 1.保证”被动关闭方“能收到最后的ACK 在TCP四次挥手中主动关闭方发送最后一个ACK后连接就进入TIME_WAIT状态如果这个ACK在网络中丢失被动关闭方即最后发送FIN的一方会重发FIN如果没有TIME_WAIT主动关闭方已经释放资源无法再响应这个FIN导致被动关闭方无法正常关闭有了TIME_WAIT主动关闭方可以在这段时间内重发ACK确保双方能正常关闭 2.防止”旧连接的数据包“影响新连接 如果刚关闭连接马上又建立了相同四元组的新连接网络中延迟的旧数据包可能会被新连接接收到造成数据混乱TIME_WAIT保证这段时间内所有属于旧连接的报文都从网络中消失避免影响新连接 为什么是2倍的MSL MSL是一个TCP报文在网络中可能存在的最长时间。第一个MSL确保本方发送的最后一个ACK能在网络中“活够”一圈即使对方没收到ACK重发FIN本方还能重发ACK第二个MSL确保网络中所有属于这个连接的旧报文都消失避免影响后续新连接 举例说明 假设主动关闭发送ACK后ACK在网络中丢失被动关闭方重发FIN主动关闭方还在TIME_WAIT可以再次发送ACK如果只等1倍的MSL可能有些报文还在网络中漂流2倍MSL可以确保通信双方历史数据都得以消散 总结 TIME_WAIT的存在是为了保证TCP连接的可靠性和安全性2倍的MSL即保证了最后的ACK的可靠连接也防止了旧数据包影响新连接 经典问题3为什么建立连接时要三次握手断开连接时要四次挥手
1.三次握手的根本目的
验证双方的收发能力并同步初始序号确保客户端和服务端都能正常”发“和”收“实现TCP的全双工特性。防止服务端资源被无效连接占用提升安全性和健壮性。
2.不能一次或两次握手的原因
一次握手
只能保证客户端能发服务端能收无法确认服务端能发客户端能收。
两次握手 1.”半连接队列“问题 如果只用两次握手服务端收到SYN后立即分配资源并进入”已连接“状态等待客户端数据但客户端可能因为网络异常恶意攻击等原因根本不会正常发送数据导致服务端白白维护了一个”无效连接“。服务端通常要同时服务大量客户端如果有大量这样的”半连接“会极大消耗服务器资源甚至被恶意利用。 2.三次握手让”连接建立的最终确认权“交给客户端 三次握手的第三步客户端收到服务端的SYNACK后只有客户端再发出ACK服务端才能认为连接真正建立。这样如果客户端不发最后的ACK服务端会在超时后自动释放资源不会一直维护无效连接。这实际上把”维护错误连接的成本“转移给了客户端保护了服务器。 总结
三次握手的设计是基于”双方能力确认资源分配安全“这两个核心目标三次是最小且足够的次数。
三次握手既保证了双方收发能力的验证也把维护错误连接的成本交给了客户端保护了服务器资源是最小且合理的设计。
1.四次挥手的根本目的
确保双方都能把剩余数据传输完并且双方都同意断开。
2.为什么不能只用两次 TCP是全双工工的双方都可以独立的发送和接收数据。关闭连接时每个方向都要单独关闭即A-B和B-A都要各自确认。如果只使用两次挥手可能会导致一方的数据还没发完连接就关闭了造成数据丢失。 以上就是关于传输层TCP协议第一部分的讲解如果哪里有错的话可以在评论区指正也欢迎大家一起讨论学习如果对你的学习有帮助的话点点赞关注支持一下吧