传输层协议

传输层的两层协议.

一是UDP,二是TCP

UDP的特点是无连接,不可靠,面向数据报

无连接:拿到对方的端口号和ip就直接进行数据传输,不用建立连接
不可靠:没有相关可靠的机制保证数据一定到达,发送后可能对方没收到
面向数据报:不能灵活的控制读写数据的次数和数量

UDP协议首部中有一个16位的最大长度. 也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部).
然而64K在当今的互联网环境下, 是一个非常小的数字

TCP的特点是有连接,可靠传输,面向字节流

可靠的意思是不能保证对方100%的收到我发送的信息

TCP的十个重要特性

1.确认应答

TCP将每个字节的数据都进行了编号. 即为序列号,每一个ACK都带有对应的确认序列号, 意思是告诉发送者, 我已经收到了哪些数据; 下一次你从哪里开始.

比如说本次主机A需要给主机B发送1000个字节,并且这些字节的序号为1-1000 (TCP的报头中写1就行了,再结合TCP的报文长度就能确定发送的字节序号是1-1000)
那么当主机B收到这1000个字节的数据之后呢就会返回给A一个序列号为1001的应答报文,这样就相当于告诉主机A,我已经收到了序列号1-1000的字节,下一次请从1001号开始发送

2.超时重传

很多情况下数据包可能会在传输过程中丢失,所以需要发送方重新发送一份数据

当主机A给主机B发送1000个字节,并且序号还是为1-1000,当主机A发送后会启动一个定时器,如果过了一定时间,主机B还没返回给主机A一个应答报文,那么此时主机A会再次给主机B发送一份同样的数据,这个过程就叫超时重传, 但是需要注意的是,TCP是抱着一种悲观的态度,当一次丢包重传之后,TCP会觉得后面再发送数据可能也会丢包,所以说下次重传间隔的时间会更长.

3.连接管理

1)建立连接,三次握手

建立连接的作用:

  1. 更好的保证可靠性,验证双方通信能力是否正常
  2. 协商一些重要参数

过程
比如主机A向主机B发起连接,在建立连接之前它们都处于关闭状态
当主机B的服务器绑定服务器地址和端口之后,那么主机B这边就进入LISTEN状态,就可以监听连接请求
当主机A创建一个scoket对象绑定服务器ip和端口之后就会进入SYN_SEND状态,因为此时主机A会发送连接请求,这一步相当于测试主机A的发送能力,并且阻塞等待服务器的回应
当主机B接收到来自主机A的syn后,主机B就会进SYN_RCVD状态,也证明主机A的发送能力没有问题, 自己的接受能力没有问题, 主机B会给主机A发送一个报文,这个报文的ACK和SYN字段都置为1,相当于告诉主机A你的发送没问题, 并且测试自己的发送能力
那么当主机A收到来自主机B的报文之后就证明通信双方的通讯能力都没问题,于是主机A进入ESTABLISHED状态,并且发送一个ACK给主机B,相当于告诉主机B你的发送能力也没问题
当主机B收到这个ACK报文时,主机B就知道自己的发送能力没有问题,于是也进入ESTABLISHED状态完成连接.

2)断开连接,四次挥手

比如现在是主机A想要断开连接,那么主机A会给主机B发送一个FIN报文,并且进入FIN_WAIT_1状态
当主机B收到这个报文之后会由内核立即发出一个ACK报文,并且进入CLOSE_WAIT状态,
当主机A收到ACK报文之后,主机A就会进入FIN_WAIT_2状态,并且等待主机B的FIN报文
等到主机B把接收缓冲区中的数据处理完之后,调用socket的close方法,就会向主机A发送一个FIN报文,并且进入一个LAST_ACK状态
当主机A接收到这主机B的FIN报文之后就会进入TIME_WAIT状态,随后发送ACK报文,当他发送后保持一段时间进入CLOSE状态
当主机B接收到这个ACK之后也就进入CLOSE状态,此时双方的连接关闭

4.滑动窗口

意义:
在可靠传输的前提下,提高传输效率,将N份数据的传输时间合成一份数据传输的时间

没有滑动窗口的话,一次发送一个数据报,等待一个ACK,再发送下一个数据报
依靠滑动窗口就能一次发送多个数据报,等待多个ACK.
比如说现在一次要发送四个报文,每个报文包含1000个字节,字节序号从1开始编号,发送出去以后,就会等待对应的应答报文,当收到相应的报文之后,窗口也会向后面滑动,也是说收到相应的ACK之后就再后面的数据,但是每次发送的不一定是一个,也不一定是4个,窗口滑动的距离也就是不确定的,可以说窗口里面的数据就是已经发送过的数据,在等待对应的ACK报文,整个发送过程就是窗口不断滑动的过程.

如果ACK丢了怎么办?
ACK丢包了就不用管,引发超时重传之后总会收到对应的数据.

如果数据包丢了怎么办?
如果数据包丢了,那么主机B就会一直返回同一个确认序号的应答报文,当主机A三次接收到这样的报文,主机A就知道对方没有收到这个包,于是就会再次发送对应的数据.

5.流量控制

接收方的处理速度是有限的,所以窗口大小不能无限大,如果数据传的太快,那么接收方可能会处理不过来,而导致一系列问题,所以需要根据接收方的处理能力来制约发送方的发送速率
那么这个机制就利用接收方的接收缓冲区剩余空间大小来决定

当主机A给主机B发送数据的时候,数据会先存到主机B的接收缓冲区中,主机B调用read方法就是从缓冲区中读取数据,被read读到的数据就可以从缓冲区中删除了
接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段, 通过ACK端通知发送端,从而限制发送方的发送速率.

接收端一旦发现自己的缓冲区快满了, 就会将窗口大小设置成一个更小的值通知给发送端,发送端接受到这个窗口之后, 就会减慢自己的发送速度;
如果接收端缓冲区满了, 就会将窗口置为0; 这时发送方不再发送数据, 但是需要定期发送一个窗口探测数据
段, 使接收端把窗口大小告诉发送端.

6.拥塞控制

拥塞控制就是考虑网络上的拥堵情况来确定窗口大小,主要是使用反复试探的方式来决定窗口大小.
TCP引用的是慢启动的方式,一开始发送很少的数据,当网络情况良好时,窗口大小呈指数规律增长,当增长到阈值时就会改为线性增长
随后一旦出现拥堵(丢包),窗口就会一下回到初始值,再重复之前的指数增长和线性增长过程,但是此时的阈值变成出现拥堵情况时窗口大小的一半,拥塞控制就是通过这样的过程来决定窗口大小

7.延时应答

目的是为了提高效率在流量控制的基础上,尽量返回一个合理的但是又比较大的窗口.

如果接收数据的主机立刻返回ACK应答, 这时候返回的窗口可能比较小.
假设接收端缓冲区为4000. 一次收到了1000的数据; 如果立刻应答, 返回的窗口就是3000;
但实际上可能处理端处理的速度很快, 可能很短的时间内就能处理完
在这种情况下, 接收端处理还远没有达到自己的极限, 即使窗口再放大一些, 也能处理过来;
如果接收端稍微等一会再应答, 那么这个时候返回的窗口大小就是4000;

8.捎带应答

在延迟应答的基础上,为了进一步提高效率而引入的机制

客户端和服务器之间的通信模式一般都是Request-Response模式.“一问一答”
主机B要给主机A返回两个数据. (ACK-RESP)
严格的说,这两个数据的传输时机是不一样的

内核收到数据,就会立刻返回ACK应用程序代码执行完了"根据请求计算响应"
把响应写回给客户端,才发送的响应.

ACK如果采用延时应答,那么在ACK等待的这段时间里,应用程序代码完成了响应的计算.
应用程序在写回Resp的时候正好发现刚才的ACK还没发呢,就在这个Resp数据报的基础上,顺便带上ACK信息.

9.粘包问题

我们发送的数据都会被接收方暂存到接收缓冲区中,那么接收方对缓冲区的数据读法不一样,最终读取到的含义也就不同,
所以就应该使用一些规定的方式去读取数据,区分出包和包之间的边界,
那么可以使用分隔符,也可以明确指定包的长度
对于HTTP协议来说,这两种方法都用到了,当处理get请求时就使用空行作为分隔符
处理post请求时,使用Content-Length指定包的长度

10.保活机制

在一些"异常情况"下,TCP对于连接会有特殊的处理.

  1. 进程崩溃这种情况下,TCP连接会正常四次挥手.(只要是进程退出,都会自动关闭相关的文件)
  2. 主机关机按照流程关机):关机的时候会强制先杀进程杀进程过程中就进行四次挥手了.
  3. 主机断电/网线断了(重点):
    1. 接收方断电, 发送方尝试发送消息的时候,就会出现没有ACK的情况=>超时重传=>重传一定次数,重置连接=>放弃连接.
    2. 发送方断电, 接收方尝试接受消息对于接收方来说,本来也不知道发送方啥时候发送,这种时候心跳包的作用就体现出来了
    3. 心跳包 : TCP的通信双方,即使在没有数据交互的过程中,也会定时相互传输一个没有实际业务意义的"心跳包",只是为了证明“我活着",一旦隔了一段时间都没有收到对方的心跳包,就可以认为对方已经下线了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值