重庆宣网站建设,贵州网络推广咨询,顺德营销型网站,2022热门网页游戏排行榜TCP笔记 概念 MTU#xff1a;maximum transmission unit最大传输单元 每种网络都不一样#xff0c;以太网是1500。最小46字节。当数据块大于MTU时#xff0c;将在发送端IP层进行分片#xff0c;接收端IP层进行重组。IP分组在网络中传输中出现丢包时#xff0c;由于IP层没有…TCP笔记 概念 MTUmaximum transmission unit最大传输单元 每种网络都不一样以太网是1500。最小46字节。当数据块大于MTU时将在发送端IP层进行分片接收端IP层进行重组。IP分组在网络中传输中出现丢包时由于IP层没有重传机制TCP将重传整个报文段而不是丢失的IP分组 PS: 以太网最小数据帧长度为最小64字节其中6字节目的地址 、字节6源地址、2字节类型、46字节数据、4字节校验和. MSSmaximum segment size最大分段大小 MSS是TCP数据包每次能够传输的最大数据分段。为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值这个值TCP协议在实现的时候往往用MTU值代替需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes所以往往MSS为1460。通讯双方会根据双方提供的MSS值得最小值确定为这次连接的最大MSS值。 MSLMaximum Segment Lifetime报文最大生存时间 报文在网络上存在的最长时间超过这个时间报文将被丢弃。在RFC793指出MSL为2分钟实际应用中常用的是30秒linux1分钟和2分钟等。 TTLTime To Live生存时间 生存时间是由源主机设置初始值但不是存的具体时间而是存储了一个ip数据报可以经过的最大路由数每经过一个处理他的路由器此值就减1当此值为0则数据报将被丢弃同时发送ICMP报文通知源主机。 RTTround-trip time客户到服务器往返所花时间 RTT由三部分组成链路的传播时间propagation delay、末端系统的处理时间、 路由器缓存中的排队和处理时间queuing delay。 其中前两个部分的值对于一个TCP连接相对固定路由器缓存中的排队和处理时间会随着整个网络拥塞程度 的变化而变化。所以RTT的变化在一定程度上反应了网络的拥塞程度。 RTORetransmission TimeOut重传超时时间 重传机制依赖于RTTRound Trip Time的测量从而计算RTORetransmission Timeout。 TSOTCP Segment Offload 是一种利用网卡的处理能力降低CPU发送数据包负载的技术。对于支持TSO的网卡TCP协议栈在封包的时候会逐渐尝试增大MSS网卡接收到TCP向下递交的数据后按照MTU进行分片、复制TCP头且重新计算校验和这样在网卡上完成了对大块数据的TCP分段缓解了CPU的计算压力。 查看是否开启TSO sudo ethtool -k eth0关闭和打开TSO $ sudo ethtool -K eth0 tso off // 关闭tso$ sudo ethtool -K eth0 tso on // 开启tso TCP协议结构 source port destination port:源端口和目标端口注意不包括IP是因为这是上一层IP层的事情这一层传输层只负责找到对应的端口即应用程序。sequence number用来标记包的顺序。一个TCP包最多能传1460字节对于超出的包需要分片为了保证对端收到的包是顺序完整的需要通过seq num来重新组装数据包。值是本报文段所发送的数据的第一个字节的序号。acknowledgment number由于tcp是可靠的传输发送端需要确认对端是否收到包所以需要ack num来确认如果没有收到则会启动重传机制。ack num是期望收到对方的下一个报文段的数据的第一个字节的序号header由于tcp header有可选字段所以长度不定。所以需要这个值作为offset来表示tcp头有多大。reserved保留字段应填为0.Tag位URG为1表示有应急指针ACK除SYN包外都为1确认应答字段有效PSH为1表明将接受的数据立即传给上层协议0则先进行缓存RST为1表示强制断开连接要求对方重置连接SYN为1表示建立连接发送方向对方发送建立连接的请求FIN为1表示结束连接告知对方要中断连接Window滑动窗口值告知对端当前能接收的最大字节数进行流量控制CheckSum校验和由发送端填充接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否被篡改。注意这个校验不仅包括TCP头部也包括数据部分。Urgent Pointer紧急数据指针紧急数据指的是发送端告诉接收端这个数据是非常紧急的请优先读取多用于中断。Options扩展使用不定长但最长不超过40字节可靠性 TCP被称为可靠的传输协议所谓的可靠其实是相对UDP的不可靠而言。不是保证数据一定被对方接收。而是提供数据的可靠传递以及故障的可靠通知。 从TCP头中的几个字段来解释为什么TCP是可靠的。 seq num:确保接收端收到的报文有序并检测丢失分组和冗余分组ack num:确保接收端正确收到分组以及期望下一个分组checksum:校验数据是否篡改window:流量控制解决接收端处理数据不及时导致接收缓冲区被填满后丢失数据数据在各网络层的封装 补充阅读 理解sequence number acknowledgment nuber 漫谈TCP 三次握手、四次挥手 上面两个图来从不同的角度来看TCP的状态转换。上图来自经典的unp比较完整的表述了状态转换下图来自网上则通过三次握手四次挥手客户端与服务端状态的变化来表述。 三次握手 LISTEN:服务端bind端口以后对端口进行listen进入accept等待连接的到来服务端的状态进入LISTEN。SYN_SENT:客户端调用connect发起TCP请求等待对端返回ACK进入SYN_SENT。SYN_RECV:服务端收到SYN返回SYNACK等待对端返回ACK进入SYN_RECV。ESTABLISHED客户端发送完ACK认为连接建立进入此状态这时候其实并不确定服务端是收到ACK的如果服务端没收到ACK会重传SYNACK客户端收到以后重传ACK。服务端接收到ACK以后进入ESTABLISHED状态。四次挥手 与TCP连接不一样的断开的时候需要四次挥手。 从上面的状态转移图可以看出四次挥手要比三次握手复杂。 FIN_WAIT_1:主动断开端图中画的是客户端也可以是服务端发送FIN并等待对端ACK。实际中此状态很难观察到因为对端会非常快回复ACK所以肉眼很难观察到。但是看网上也有一些情况下会有大量FIN_WAIT_1。CLOSE_WAIT:被动断开端收到FIN回复ACK等待本机应用断开连接。如果本机在忙于读或写或者代码处理有误没有关闭连接。就会出现大量的CLOSE_WAIT。FIN_WAIT_2:主动断开端收到ACK等待对方发送FIN。FIN_WAIT_2状态下的SOCKET表示半连接也即有一方要求close连接但另外还告诉对方我暂时还有点数据需要传送给你稍后再关闭连接。如果对方一直不发送FIN则会一直停留在FIN_WAIT_2。LAST_ACK:被动断开端发送FIN等待对方ACK。TIME_WAIT:主动断开端收到FIN响应ACK等待2MSL。这是为了防止最后一个ACK可能被丢失了那么在2MSL中如果收到对方重复发送的FIN包就需要重新发送ACK来关闭连接。TCP的这种行为我们可以看作是一种负责任的行为主动请求关闭的一方在很大程度上确保了对方收到断开确认请求之后才关闭这个连接的。如果在大并发的短链接下TIME_WAIT就会太多这也会消耗很多系统资源。解决办法可以对系统参数调优解决另外服务端不主动断开是个好主意如果是HTTP服务器设置connection:keep-alive让客户端去主动断开。参考TCP的那些事儿CLOSING:这是比较特殊的状态在两端同时关闭的时候出现当连接双方的应用同时执行close操作时将导致双方进入FIN_WAIT_1状态当双方各自收到对段发送的FIN后状态变迁为CLOSING且发送最后的ACK。当收到最后的ACK后状态变化为TIME_WAIT。分别等待2MSL关闭到CLOSED2MSL 2MSL是为了确保有足够的时间让对端收到了ACK如果被动关闭的那方没有收到Ack就会触发被动端重发Fin一来一去正好2个MSL。 由于2MSL的存在在TIME_WAIT状态下该连接涉及的客户端和服务端端口不能被使用为了绕过此限制的方法SO_REUSEADDR详细介绍见后续章节。通过设置此值TCP服务器能够快速成功重启对于多网卡客户端在对长连接服务器压力测试时通过设置此值绑定相同端口到多个网卡提高单机QPS。 为什么是三次握手 三次握手为了防止已失效的连接请求报文段突然又传送到了服务端因而产生错误。比如client发送了一个请求但是在网络上超时了因此又发送了一个同样的请求server收到以后给予回复。但是此时刚才无效的请求又过来了服务端再次回复了这就造成了错误。 为什么是四次挥手 为了确保数据能完整的传输。关闭连接时收到对方FIN报文表示对方数据发送完了并不表示接收端所有的数据都发送完了所以未必会立马关闭SOCKET可以在发送完数据后再发送FIN报文给对方表示现在可以关闭连接了。所以在这里ACK和FIN是分开发送的。 另一种解释这是因为TCP的半关闭特性导致的。所谓的半关闭是指TCP提供了连接的一端在结束它的数据发送后仍能接收来自对端数据的能力。半关闭也可以理解为主动关闭方完成了写数据操作但仍可以进行读操作。这也是TCP被称为全双工协议的原因。为了实现此特性TCP实现中提供了一个shutdown函数。虽然存在半关闭特性但实际的应用中却很少使用基本上都是简单粗暴的通过调用close函数来结束两个方向上的连接而不是shutdown。 补充阅读 TIME_WAIT和CLOSE_WAIT 漫谈TCP TCP的那些事儿 重传与拥塞 重传机制 重传是可靠性的保证是发送端感知到网络出现丢包主动发起重传。发送端是如何感知的呢用户主动确认超时机制接收端通过ack来告知发送端前面的ack-1个字节已经被接收未被确认的报文在超时后进行重传。 重传机制依赖于RTTRound Trip Time的测量从而计算RTORetransmission Timeout。 先假设一个场景发送端发了1,2,3,4,5一共五份数据接收端收到了12于是回ack 3然后收到了4注意此时3没收到此时的TCP会怎么办我们要知道因为SeqNum和Ack是以字节数为单位所以ack的时候不能跳着确认只能确认最大的连续收到的包不然发送端就以为之前的都收到了。 超时重传 请求包发出去的时候开启一个计时器当计时器达到时间(RTO)之后没有收到ACK,则就进行重发请求的操作一直重发直到达到重发上限次数或者收到ACK。 超时重传也有两种选择 一种是仅重传timeout的包。重传timeout后所有的数据快速重传机制 当接收方收到的数据包是不正常的序列号那么接收方会重复把应该收到的那一条ACK重复发送这个时候如果发送方收到连续3条的同一个序列号的ACK那么就会启动快速重传机制不需要等到timeout把这个ACK对应的发送包重新发送一次。 发送方发出了12345份数据第一份先到送了于是就ack回2结果2因为某些原因没收到3到达了于是还是ack回2后面的4和5都到了但是还是ack回2因为2还是没有收到于是发送端收到了三个ack2的确认知道了2还没有到于是就马上重转2。然后接收端收到了2此时因为345都收到了于是ack回6。 滑动窗口 TCP滑动窗口主要是提供TCP的流控特性解决接收端处理数据不及时导致接收缓冲区被填满后丢失数据的问题。 TCP头中的window字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据而不会导致接收端处理不过来。 从上图中看出把发送数据横拍做长列状发送方一但有数据收到ACK那么滑动窗口左侧边就进行左移。同样一旦接收方有数据被应用层消费那么滑动窗口的右侧边就进行右移。 发送窗口及发送方数据状态 已发送并得到对方ACK已发送未收到ACK未发送但对方允许发送未发送对方不允许发送。 其中已发送未收到ACK和未发送但对方允许发送的数据称为发送窗口 接收窗口接收方数据状态 已接收未接收准备接收未接收并不准备接收。 其中未接收准备接收的数据称为接收窗口 一旦滑动窗口大小缩小为0发送端将停止发送数据等待接收端新接收窗口值大于0的到来以移动滑动窗口的右边沿。上述滑动窗口机制自然能抑制发送端的发包速率但同时引入了糊涂窗口综合症。 糊涂窗口综合症Silly Window Syndrome是指接收方通告一个较小的窗口而发送方发送少量的数据的现象。要解决这个问题也不难就是避免对小的window size做出响应直到有足够大的window size再响应。 拥塞处理 如果网络不佳的情况下接收端可能会因为网络包拥塞而无法接收到而根据重传的特性发送端会在RTO时间后重传数据这样更加加剧数据拥塞。解决办法有慢启动、拥塞避免、快速重传与快速恢复 发送方维护了两个窗口拥塞窗口和滑动窗口。两者都是试图对发送窗口大小进行控制的自然发送窗口大小min{滑动窗口大小拥塞窗口大小}。当无网络拥塞发生时滑动窗口大小一般小于拥塞窗口大小。 慢启动 慢启动的意思是刚刚加入网络的连接一点一点地提速其实并不慢拥塞窗口大小呈指数上升。 拥塞避免算法 慢启动使得cwnd是呈指数增长。一定不可能是无限增长的这里就有个阀值超过这个阀值就进入拥塞避免算法。 拥塞避免算法说的是拥塞窗口的增加不再是“每收到一个ACK拥塞窗口就增加一个报文段”。 而是“每收到一个ACKcwnd cwnd 1/cwnd” 判断拥塞 超时重传 发出去一个包超时定时器就开始计时当超时定时器到时间之后没有收到ACK那么这个时候就判断为拥堵了,需要进行重传。TCP会直接把cwnd调整为1sshthread 调整为cwnd/2重新进入到慢启动流程。 快速重传 比如5个请求但是第2个请求丢失了第1、3、4、5请求到了接收端3、4、5请求触发了三个ACK返回但是由于接收端没有收到请求1返回的三个ACK都是ACK1的所以发送方就表现为收到重复ACK。当连续收到三条重复ACK的时候就进行重传不需要等待重传计时器。这个时候TCP会觉得网络还是可以的反应不会那么激烈cwnd调整为cwnd/2, sshthresh调整为cwnd大小进入快速恢复算法。 快速恢复 快速恢复算法是为了不要有一个重传就那么大响应。能尽快恢复到网络流畅时候稳定的状态。 补充阅读 TCP的阻塞和重传机制 TCP的那些事儿上 TCP的那些事儿下 漫谈TCP 转载于:https://www.cnblogs.com/zhiqli/p/5926573.html