UDP,TCP报头分析,以及TCP三次握手和四次挥手

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_37964044/article/details/80727893

*UDP协议*
一 udp协议基本格式
这里写图片描述
由上图可知udp协议报头信息一共占8字节
1.2字节的目的端口号*
表示到哪个进程去
2.2字节的源端口号*
表示从哪个进程来
3.2字节的UDP长度*
用户数据报收发长度确定,因此包含一个UDP长度字段。(udp报头和udp数据长度)
4.2字节的UDP校验和*
udp尽管不保证可靠性,即表示报文收不收的到我不管,但 我不能把一个错误的东西交给上层,如果校验和出错,就会直接丢弃
二 udp的特点
1.无连接:知道对端的IP和端口号就直接进行传输,不需要建立连接
2.不可靠:没有确认机制,没有重传机制
3.面向数据报 :不能够灵活的控制读写数据的次数和数量
4.不能一次发送太大的数据。
5.及时通信,也就是速度特别快,节约访问时间
三 如何让有效让数据和报头分离
使用定长报头
四 udp使用注意事项
我们注意到udp首部有一个16位的最大长度,也就是说一个udp能传输的数据最大长度是64K(包含udp首部)
如果我们需要传输的数据超过64K,就需要在应用层手动的分包,多次发送,并在接收端手动拼装
TCP协议
TCP全称为”传输控制协议”
一 TCP协议基本格式
这里写图片描述
1.源端口号和目的端口号
表示数据从哪个进程来,到那个进程去
2.32位序号和32位确认序号作用
..保证最基本的可靠性(有请求,有应答)
..保证数据有序到达(一次发多个不怕乱序,因为有序号)
..明确支持重传机制(你要对我的报文进行确认,一旦确认可以明确知道那部分
丢失,那部分在。也就明确知道哪部分丢了,需要重传)
(1)序号:seq序号,占32位用来标从TCP源端向目的端发送字节流,发起方发送数据时对此进行标记
(2)确认序号:ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ack=Seq+1(注意不要将Ack和ACK弄混了,确认方Ack=发起方Req+1,两端配对。)
3.4位TCP报头长度
表示TCP报头(首部)包含多少个4字节,所以TCP首部最大长度为15(1111)*4=60字
4.6位标志位
URG:紧急指针是否有效,告诉对方把数据优先处理(无序)这也是URG和PSH的区别。
ACK:确认号是否有效
PSH:提示接收端应用程序,立即从TCP缓冲区把数据有序取走。
RST:对方要求重新建立连接
SYN:请求建立连接
FIN:通知对方,本端要关闭了
5.16位滑动窗口大小
用来描述接受方,剩余缓冲区大小,有效避免了接受方的缓冲区满了,还一直发数据 导致的丢包重传问题
6.16位校验和
发送端填充,如果接受端校验不通过,则认为数据有问题。此处的校验不光包含
TCP首部也包含TCP数据部分
7.16位紧急指针
表明那部分是紧急数据,处理的时候会优先处理
二 TCP连接管理机制
TCP三次握手
TCP连接需要发送3个TCP报文来建立,就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包以确认连接的建立,这就是所谓的三次握手。在socket编程
中,这一过程由客户端执行connect来触发,整个流程如下所示:
这里写图片描述

(1)第一次握手:客户端Client主动发起连接请求,向服务器端发送“连接建立请求报文”(不携带数据),此时SYN=1(表示请求连接),并且在此期间随机产生一个序号seq=j(但是不能为0)此时客户端就进入SYN_SENT状态(同步已发送状态),等待处于监听状态的服务器应答。
(2)第二次握手:如果服务器端在接收到“连接建立请求报文”之后,如果同意建立连接,则向客户端发送第二个控制位SYN=1,ACK=1的“连接建立请求确认报文”。确认号ack=j+1,表示是对第一个“连接建立请求报文”序号(seq=j)的确认,同样“连接建立请求确认报文”不携带数据字段,但是需要给报文一个序号(seq=k).这时服务器进入
SYN_RCVD状态。
(3)第三次握手:客户端在收到“连接建立请求确认报文”之后,客户端发送第三个控制位ACK=1”连接建立请求确认报文“。由于该报文是对”连接建立请求报文“(seq=k)的确认,因此确认信号ack=k+1。同样”连接建立请求确认报文“不携带数据字段,但是也需要给报文一个序号seq=j+1(TCP协议规定),此时客户端就进入了ESTABLISHED状态,服务器端在接受到“ACK”报文之后也入ESTABLISTENED
(以建立连接)状态。
三次握手之后,随后Client和Server之间就可以开始传输数据了。
TCP四次挥手
所谓四次挥手,即是终止TCP连接,就是指断开一个TCP连接,需要客户端和服务器总共发送4个报文以确认连接的断开。在socket编程中,这一过程由客户端或服务器任一方执行close来触发。整个流程如下:
这里写图片描述
由于TCP连接是全双工的,因此每个方向都必须要单独进行关闭,这一原则是当一方
完成数据发送任务后,发送一个FIN来终止这一方向上的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再接受到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。
(1)第一次挥手:双方通信完成后,则需要释放连接。客户端发送一个控制位为FIN的报头,用来关闭客户端到服务器的数据传送。”连接释放请求报文“不携带数据字段,但是需要给报文一个序号seq=u,u等于客户端发送的最后一个字节的序号加1。此时客户端进入FIN_WAIT_1状态。
(2)第二次挥手:服务器端收到”连接释放请求报文“后,向客户端发送ACK=1的连”接释放请求确认报文“,确认号为ack=u+1,表示对seq=u报文的确认。此时这个报文段自己的序号是seq=v,等于服务器前面已传过的数据的最后一个字节的序号+1,此时服务器进入CLOSE_WAIT状态,客户端进入FIN_WAIT_2状态。
但是此处注意的是当服务器收到“连接释放请求报文”如果服务器还有数据报文要发给,它还可以继续发送,直到发送完毕。这种状态称为”半关闭“状态
(3)第三次挥手:服务器发送一个设置位为FIN的报文,用来关闭服务器到用户端的数据传送,服务器端进入LAST_ACK状态。过程和上面很像。不过此处报文的序号seq=w取决于你在”半关闭状态时,服务器端是否发送过数据报文“
(4)第四次挥手:客户端收到FIN报文后,客户端进入TIME_WAIT状态等待2MLS的时间,接着发送一个设置位ACK=1的连接释放请求确认报文。服务器端进入CLOSE状态

三 为什么建立连接不是两次握手呢?
如果是两次握手,客户端首先发送SYN=1连接建立请求报文,服务器端回复SYN=1,ACK=1的连接建立请求确认报文,但是报文却丢失(因为最新一次的报文,是无法确定的)。那么客户端收不到回复报文,认为连接请求失败,而服务器端则认为连接已经建立完成。并为此次连接管理和维护耗费资源。如果大量的客户都发生这样的情况,不断建立连接,那么 服务器端就有大量的闲置连接需要管理和维护,一直占用资源,导致服务器的负载太重。最终挂掉。(大量的恶意连接,会对服务器进行“洪水攻击”)。同样四次握手也不可以,偶数次握手都不可以。
四 为什么建立连接是三次握手呢?
如果是三次握手,客户端先发送SYN=1 ”连接建立请求报文“,服务器端回复”SYN=1,ACK=1”连接建立请求确认报文“,客户端在收到后继续向服务器发送ACK=1的”连接建立请求确认报文“,但是报文却丢失(因为最新一次的报文,是无法确定的)。此时客户端认为连接已经建立,但服务器认为连接没有建成。服务器端就不会对这个连接管理和维护。只需要客户端需要对此连接维护。不会占用服务器的资源,保证了服务器的安全。客户端认为连接建立好了,因此会给服务器端发数据,但是服务器端认为连接没有建立好,就会给客户端发送RST让客户端重新建立连接。
五 为什么第四次挥手最先断开连接的一方要等待2MSL的时间
等待2MSL的时间目的是确保最后一次ACK报文到达对方,为什么认为等2MSL的时间就能到达对方。如果没有到达对方,对方一定要给我重新发FIN.如果2MSL的时间内没有收到FIN,则保证最后一次ACK报文到达对方。(1MSL的时间指,一个报文从A端到B端要花费的最大时间)

猜你喜欢

转载自blog.csdn.net/baidu_37964044/article/details/80727893