TCP UDP

TCP

TCP 报文结构

TCP报文一共有20个字节
UDP只有8个字节
在这里插入图片描述

三次握手

在这里插入图片描述 确认ACK:仅当ACK=1时确认号(ack)才有用,当ACK=0时确认号无效。TCP规定,连接建立后的ACK都置为1。
同步SYN:连接建立时用来同步序号。当SYN=1,ACK=0时表明这是一个请求报文段。响应的报文段中SYN=1,ACK=1。SYN=1表明这是一个连接请求或者连接接受阶段。
终止FIN:释放一个连接。当FIN=1时表明此报文段的数据已经发送完毕,要求释放运输连接。
(1)第一次握手:建立连接时,客户端A发送SYN包[SYN=1,ACK=0,seq=x](随机选择一个初始序号seq=x)到服务器B(SYN=1的报文段不携带数据,但消耗掉一个序号),并进入SYN_SENT状态(同步已发送),等待服务器B确认。
(2)第二次握手:服务器B收到SYN包,必须确认客户A的SYN,同时自己也发送一个SYN包,即SYN+ACK包[SYN=1,ACK=1,seq=y,ack=x+1],此时服务器B进入SYN_RECV状态(同步收到)。
(3)第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK[ACK=1,seq=x+1,ack=y+1],此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据。在socket编程中,客户端执行connect()时,将会触发三次握手。

为什么需要三次握手呢?

主要是为了防止已经失效的连接请求报文段突然又到达了B,因而产生错误。
B认为A要建立连接,所以就向A发送确认报文段建立了连接,但是A没有建立连接的请求,因此不会理睬B的确认,也不会向B发送数据,但是B却一直在等待,造成资源的浪费

三次握手中可能出现的问题

可能出现的问题及解决方案:

1.Server收到Client的SYN,回复SYN+ACK的时候未收到ACK确认。则Server不断重试直至超时,Linux默认等待63秒才断开连接。
SYN超时可能会带来恶意代码攻击,应对SYN Flood的防护措施是:
->SYN队列满后,通过tcp_syncookies参数回发SYN Cookie,若为正常连接则Client会回发SYN Cookie,直接建立连接。

2.建立连接后,Client出现故障怎么办?
保活机制:
向对方发送保活探测报文,如果未收到响应则继续发送,尝试次数达到保活探测次数仍未收到响应则中断连接

四次挥手

表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN WAIT1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

在这里插入图片描述 客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。TCP要保证在所有可能的情况下使得所有的数据都能够被投递,当你关闭一个socket时,主动关闭一端的socket将进入TIME_WAIT状态,而被动关闭一方则转入CLOSED状态 ,这能够保证所有的数据都被传输。
(1)首先A B端的TCP进程都处于established状态, 当A的应用程序传送完报文段,就会去主动关闭连接。A会停止发送报文段(但是还会接收),并向B发送[FIN = 1,seq=u](u等于前面已经发送过的数据的最后一个字节加一)数据,之后进入FIN-WAIT-1状态。
(2)B接收到A发送的请求之后,会通知应用进程,A已经不再发送数据,同时B会向A发送ACK确认数据[ACK=1,seq=v,ack=u+1 ],B进入CLOSE-WAIT状态(关闭等待),A接收到B发送的数据之后,A进入FIN-WAIT-2状态;此时A到B方的连接已经关闭了(即半连接状态)。
(3)当B的应用进程发现自己也没有数据需要传送,B应用进程就会发出被动关闭的请求,B此时向A发送[FIN=1,ACK=1,seq=w,ack=u+1]数据,并且进入LAST-ACK状态(最后确认)。
(4)A接收到B发送的数据之后,向B发送ACK确认数据[ACK =1,seq=u+1,ack=w+1],进入TIME-WAIT状态,等待2MSL(Maximum Segment Lifetime,报文最大生存时间)之后正常关闭连接进入CLOSED状态;B接收到A发送的确认之后进入CLOSED状态。B到A方的连接关闭!至此,TCP连接才真正全部关闭!

time_wait时间过长占用端口

HTTP协议1.1版规定default行为是Keep-Alive,也就是会重用TCP连接传输多个request/response,一个主要原因就是发现了这个问题。

  • 缩短2MSL时间
  • 打开系统的TIMEWAIT重用和快速回收。
close_wait过多的原因与解决办法

从程序的角度分析
closewait产生在服务端接收到FIN请求和返回ACK后,服务器端代码没有socket.close指令没有发送FIN结束标志 所以一直在close.wait。可能是系统忙于处理读、写操作,而未将已收到FIN的连接,进行close。

大量timewait的原因

在高并发短连接的情况下,连接时间远小于2MSL 所以会导致不能及时释放
需要调低2MSL时间或者通知内核,这时候timewait状态的端口可以复用

time_wait 状态存在2MSL的原因

1.确保有足够的时间让对方收到ACK包
主动关闭连接发送的ACK(4次交互的最后一个包)在网络中丢失,那么由于TCP的重传机制,执行passiveclose的一方需要重发其FIN 然后再

2.避免新旧连接混淆
主动关闭的一方主动调用close后,此时的TCP连接进入TIME_WAIT状态,处于该状态下的TCP连接不能立即以同样的四元组(源IP,源端口,目的IP,目的端口)建立新连接,即发起active close的那方占用的local port在TIME_WAIT期间不能再被重新分配。由于TIME_WAIT状态持续时间为2MSL,这样保证了旧TCP连接双工链路中的旧数据包均因过期而消失,此后,就可以用相同的四元组建立一条新连接而不会发生前后两次连接数据错乱的情况。

滑动窗口与拥塞窗口

TCP的三次握手四次挥手保证了连接的可靠性
TCP的流量控制的主要机制就是滑动窗口,保证了传输的可靠性
滑动窗口与拥塞窗口的介绍

超时重传机制

两个参数 RTT(传输往返时间)发送一个数据包收到ACK的时间
RTO(超时重传间隔)
理论上RTO=RTT+△T

closing 状态

CLOSING: 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

UDP

UDP报文结构

UDP报文一共8个字节
在这里插入图片描述

UDP的特点

  1. 面向非连接的

2.不维护连接状态,支持同时向多个客户端传输相同的消息

3.数据包报头只有8个字节,额外开销比较小

4.吞吐量只受限于生成速率、传输速率以及及其性能

5.尽最大努力交付,不保证可靠交付,不需要维持复杂的链接状态表

6.面向报文,不对应用程序提交的报文信息进行拆分或者合并

TCP与UDP区别

(1)TCP提供的是面向连接的、可靠的数据流传输;UDP提供的是非面向连接的、不可靠的数据流传输。
(2)TCP提供可靠的服务,通过TCP连接传送的数据,无差错、不丢失,不重复,按序到达;UDP尽最大努力交付,即不保证可靠交付。
(3)TCP面向字节流;UDP面向报文。
(4)TCP连接只能是点到点的;UDP支持一对一、一对多、多对一和多对多的交互通信。
(5)TCP首部开销20字节;UDP的首部开销小,只有8个字节。
(6)TCP的逻辑通信信道是全双工的可靠信道;UDP的逻辑通信信道是不可靠信道。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值