传输层协议-TCP协议

TCP协议的特性

有连接

tcp协议是应用于传输层的协议,发送方向接收方发送信息之前是需要和接收方建立连接的.只有和接收方进行三次握手进行连接之后才能向传输放发送数据.

可靠传输

这里的可靠传输指的不是100%能把数据传输到接收方,而是能知道传输方到底有没有接收到数据.

面向字节流

tcp协议传输数据的单位是以字节为单位的.

全双工

发送方和向接收方发送信息,接收方也能向发送方发送信息.

TCP协议的报文结构

tcp协议的报文结构如下:

源端口号/目的端口号:

表示数据是从哪个进程来的,要发送到对端主机的哪个进程.

32位序号:

表示tcp数据中每个字节的序号.tcp使用序号来保证数据的有序性和可靠性传输.发送方在发送数据的时候会给每个数据字节分配一个唯一序号.接收方则可以根据这些序号确认已经收到的数据,并且能根据数据来对数据进行排序和组合.

32位确认序号:

这个字段用来确认已经成功接受的数据字节序号.接收方在接收到数据之后会发送一个应答报文,其中包含确认序号,告知发送方已经成功接收到了哪些数据.发送方接收到应答报文之后就能知道哪些数据被成功接收,可以相应的调整发送窗口和进程超时重传.

4位首部长度: 

4个比特位表示0 - 15,但是这里的单位是4个字节,所以tcp的报文长度为60个字节.udp报头中前20个字节为固定长度,"选项"部分可有可无,可以有也可以没有,可以有一个也可以有多个.

保留(6位):

 udp协议的报文长度受到2个字节的限制,如果想要扩展就会发生机器发送udp数据报和其他机器不兼容的问题,就无法通信.所以tcp协议设计报头的时候就准备了几个保留位.后面需要使用了就可以把保留位使用起来. 

6位标志位: 

URG:紧急指针是否有效.

ACK:确认号是否有效.

PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走.

RST:对方要求重新建立连接,我们把携带RST标识的成为复位报文段.

SYN:请求建立连接,把携带SYN标识的成为同步报文段.

FIN:通知对方,本端要关了,称携带FIN标识的为结束报文段.

16位窗口大小:

用于指示发送方滑动窗口的大小.接收方使用这个字段来告知发送方自己的接收能力,以进行流量控制.

16位校验和:

用于检测数据在传输过程中是否发生了错误,如比特翻转. 

16位紧急指针:

标识哪部分数据是紧急数据. 

选项:

TCP报头当中允许携带额外的选项字段,最多40字节。可以有也可以没有. 

数据:

用于携带应用层数据.

TCP协议的特性

确认应答

        确认应答是保证可靠性的机制之一.是通过序号和确认序号来完成的.服务器和客户端之间传输数据包的时候,接收方需要给发送方发送一个ack应答报文,来告诉发送方数据包没有丢包,发送成功了.

超时重传

        双方在进行网络通信时,发送方发送的数据在一定的时间间隔之中得不到对方的应答,此时发送方就会进行数据重发,这就是TCP的超时重传机制.

        发生了丢包就会采取超时重传的措施,可能是发送的数据包丢了,也可能是ack应答报文丢了

1.发送的数据包丢了:

        发送的数据包丢了,那么发送方就接受不到接收方发送的ack报文,如果发送方长时间接收不到接收方发送的ack应答报文,发送方就会重新发送和丢失数据包一样的数据报,然后等待该数据包的应答报文.

2.接收方发送的ack报文丢了

        发送方长时间没有接收到接收方发送的ack应答报文,那么发送方也会认为丢包了.这时发送方就会重新发送数据包,但是前面的数据包是成功被接收方接收了的,如果后面重新传输的数据包到达接收方的接收缓冲区的时候前面的这个数据包已经被接收方的Socket对象read了,那么接收方就会根据读取的序列号来丢弃后面这个发送的数据包,如果前面这个数据包还在接收方的接收缓冲区中没有被Socket对象读取,那么接收方就会根据序列号来去重.

连接管理

        什么是连接?

        就是保存对端的信息,形成一个抽象的连接,断开连接就是把对端的信息删除.

三次握手(建立连接)

        TCP协议通过三次握手来建立连接

        第一次是客户端发送一个syn数据报(SYN标志位被设为1)给服务器来告诉服务器想要和它建立连接.

        第二次是服务器发送一个syn数据报+ack应答数据报(这两个数据报能合并成一个,因为SYN标志位和ACK标志位不冲突,SYN标志位和ACK标志位都设为1),告诉客户端接受连接,并且接收到了客户端发送的syn数据报.

        第三次是客户端发送一个ack数据报(ACK标志位设为1),告诉服务器接收到了它发送的syn数据报.

为什么是三次握手?两次行不行?四次行不行?

因为三次握手能刚好让双方都成功发送syn报文并且接受到ack报文.

两次握手不行,因为两次握手不能让客户端发送ack数据报,也就不能让服务器知道它第二次发送的数据报有没有发送成功.

四次握手行,因为把第二次握手的syn同步报文段和ack数据报分开发送就是四次握手.

三次握手的具体意义是什么? 

建立可靠连接

能测试传输线路同步通常

测试服务器和客户端的发送和接收功能正不正常

能商量一下传输报头中的选项配置

三次握手时的状态变化 

最开始时客户端和服务器都处于CLOSED状态

服务器为了能够接收客户端发来的连接请求,需要由ClOSED状态变为LISTEN状态.LISTEN状态表示服务器这边的ServerSocket对象已经创建好了,端口号绑定好了,可以建立连接了.

此时客户端就可以向服务器发起三次握手了,当客户端发起第一次握手后发送SYN给服务器,状态变为SYN_SENT状态.

处于LISTEN状态的服务器收到客户端的连接请求之后,发送SYN+ACK给客户端.服务器此时进入SYN_RECV状态,表示服务器收到了来自客户端请求连接的SYN报文.

客户端收到服务器发来的第二次握手后,紧接着向服务器发送最后一次握手,此时客户端的连接已经建立,状态变为ESTABLISHED.

而服务器收到客户端发来的最后一次握手后,连接也建立成功,服务器状态变为ESTABLISHED,此时TCP连接已经建立成功.

四次挥手(断开连接)

        TCP协议通过四次挥手来断开连接

以服务器和客户端为例,当客户端与服务器通信结束后,需要与服务器断开连接,此时就需要进行四次挥手

第一次挥手客户端发送FIN报文给服务器,表示请求与服务器断开连接.

第二次挥手服务器收到客户端发来的FIN报文之后发送ACK报文,表示收到客户端发来的请求断开连接的相应

第三次挥手服务器发送FIN报文给客户端,表示要和客户端断开连接

第四次挥手客户端发送ACK报文给服务器作为应答.

四次握手的状态变化

四次挥手时的状态变化如下:

在挥手前客户端和服务器都处于连接建立后的ESTABLISHED状态.

客户端为了与服务器断开连接主动向服务器发起连接断开请求,此时客户端的状态变为FIN_WAIT_1.

 服务器收到客户端发送来的FIN报文之后,发送ACK报文给客户端作为应答,并进入CLOSE_WAIT状态 .

客户端收到ACK报文之后变为FIN_WAIT_2状态

服务器还会发送一个FIN报文给客户端,表示自己也同意断开连接.此时服务器进入LAST_ACK状态.

客户端收到服务器的FIN报文之后,发送一个ACK报文给服务端,表示收到服务端的关闭请求连接.客户端进入TIME_WAIT状态,等一段时间(通常是2MSL,即两倍的最大报文段寿命),确保服务端收到ACK.

服务器收到ACK之后连接关闭,进入CLOSED状态.而客户端在等了2MSL之后,客户端也进入CLOSED,完成连接的关闭.

TIME_WAIT存在的意义

TIME_WAIT存在的意义主要是为了防止,最后一个ACK丢包.

如果第四次挥手的ACK丢包了,那么在这个等待的时间里,服务器还能重传FIN,并且等待客户端相应.

滑动窗口

在TCP协议的应答机制下,每发一条报文,都要等这条数据的ack应答报文才能发送下一条数据.这导致大量的时间都消耗在等待ack上面了.此处等待消耗的时间是非常多的.而在滑动窗口机制下,不一条一条等ack应答报文,而是统一发一波数据之后在统一等待一波ack.把多次请求的等待时间,使用一份时间来等,减少了总的等待时间.

这个统一发一波数据的数据量就称为窗口大小.

        滑动窗口出现丢包情况:

        1.ack丢了,如果应答前面数据报的ack丢了,但是这是收到后面数据报的ack应答报文,就会不有任何事发生.

        2.数据报丢了,如果数据报丢了,那么接收方就会一直发送需要这个数据报的应答报文,比如序号为1001-2000的数据报丢了,那么接收方就会发送ack报文表达下一个是1001,发生三次重复确认(因为在网络传输中可能发生先发后置的情况所以要多次确认)应答,那么发送方就会重新发送1001-2000的数据报.

流量管理

滑动窗口可以提高传输效率,但是窗口大小不能无限大.

如果窗口太大,发送速度过快,接收方处理不过来,接收缓冲区满了,那么在继续发就会丢包,这时候就需要tcp数据报报头中的窗口大小字段来调整窗口大小了.

窗口大大小不止报头中的16位,在报头的选项字段中还存在一个参数叫窗口扩展因子,实际上真实的窗口大小是16窗口大小*2^窗口扩展因子.

接收方会根据自己缓冲区剩余空间大小来设置ack报文中的窗口大小和选项中的窗口扩展因子,发送方会根据收到的ack应答报文中这个数据来调整窗口大小.

拥塞控制

流量控制是站在接收方角度考虑的,而拥塞窗口是站在传输链路的角度来考虑的.

因为就算接收方处理数据的速度再快,但是如果传输的路径在堵塞,那么也会造成丢包的现象.

但是把窗口大小调小就能尽量避免在传输路径中阻塞的情况,

发送方在发送数据的时候会从很小的数据量开始传输,然后在慢慢调大窗口大小,如果窗口带线啊哦达到一定程度开始丢包了,那么减小窗口大小,或者重新开始.具体的做法就是:

1.发送方开始发送一个很小窗口的数据报,然后把窗口大小按指数级别增大.

2.窗口大小增大到设定的阈值之后,就会按照线性增大,就是加上一个数的大小增大.

3.增大到数据丢包的时候就会减小窗口的大小到初始值.

4.然后按照上述过程重新增大窗口大小,但是阈值会重新设定

上述这种出现丢包就回到初始值的方法已经废弃了

新的方法是增大到丢包就直接把窗口大小设为新的阈值,不在从很小的窗口大小开始发送,而是从一个比较大的值开始发送.然后增大,重复上述过程.

流量管理和拥塞控制都会控制发送方的窗口大小,但是发送方真正的窗口大小就是哪个产生的窗口小,哪个说了算.

流量管理和拥塞控制的区别 

        流量管理是为了控制发送方发送数据的速率,以便使接收方能够处理并消化这些数据,防止接收方因处理不及时而丢失数据或发生溢出.

        拥塞窗口是为了防止网络拥塞而进行的控制,它关注的是网络链路的负载情况,可以避免因网络拥塞而导致的丢包和网络性能下降.

延时应答

        接收方收到数据之后不立刻发送ack,而是延迟一段时间在发送ack应答报文.这样做可以减少网络流量,提高网络利用率.发送方不需要收到每个数据报的ack,而是收到后面的ack就能知道前面的数据已经收到了.

        如果接收方收到大量数据之后立刻就返回ack,那么ack中的滑动窗口就比较小,进而就会导致传输效率变慢,而等一段时间之后在返回ack,那么这时接收缓冲区的数据已经被读取了一些,那么窗口大小就会比较大,这样就可以提高传输效率.

捎带应答

        修改窗口大小是一条提高传输效率的有效途径.而捎带应答是走的另一条路径,就是把能合并的数据报进行合并,从而起到提高效率的效果.

        在延时应答的作用下,ack应答报文可能会和其他数据报一起发送.

在延时应答和捎带应答的作用下四次挥手可能合并成三次. 

面向字节流

        因为tcp协议是面向字节流的,那么就会发生"粘包问题",tcp传输的数据到了接收缓冲区之后,接收方read读取数据的时候,就会发生分不清从哪里到哪里是一个数据包,而且一个tcp数据报可能不知携带一个应用层数据包,那么解决这个问题的关键就是"明确包之间的边界"的两种方案:

1.用分隔符区分包之间的边界,但是这个分隔符要是数据包中不可能出现的符号,见到分隔符就认为一个包结束了.

2.指定数据包的长度,比如在数据包开始的地方加上一个空间来表示数据的长度

上述两种解决方案就是在设计应用层协议的时候就要考虑好的. 

异常情况

1.进程崩溃

无论进程是正常结束还是异常崩溃,都会导致文件资源释放,然后触发四次挥手.tcp连接的生命周期比进程长一些,虽然进程结束了但是tcp连接还在,任然可以继续四次挥手,虽然进程不在但是系统中任然有连接的信息,以便完成后续挥手的过程.

2.其中有一方出现了关机

出现关机会强制终止所有进程,此时4次挥手不一定能完全挥完.如果快的话能挥完断开连接.如果不能挥完,至少挥了一次,那么就就是发送了第一个FIN,那么没关机的那方就会发送ack+fin,此时没关机那方就会等ack,但是迟迟等不到就会进入超时重传的流程,重传几次都没用就会单方面释放信息

3.有一方出现了断电

1.接收方出现断电,那么发送方就一直接收不到ack,就会重传,重传几次还是不行就会复位连接,需要用到复位报文段

发送复位报文段还是没有ack,重置了还是不行,就会单方面断开连接.

2.发送方出现了断电,那么接收方就会发现接收不到数据,就会发送"心跳包"(即使主机通过tcp连接,但是任然会用应用层自己设置的心跳包,而不用tcp的心跳包,因为tpc心跳包周期比较长),询问对方是否挂了,还是好着没法,如果对端没心跳就会尝试复位,不行就单方面断开连接. 

4.网线断开

就是3中1和2的结合

异常总结:

其实就是两种情况

一种正常断开连接,就是进程崩溃这种.

另一种就是异常断开连接,通过超时重传次数过多或者复位报文段和心跳包来断开连接.

用UDP如何实现可靠传输? 

可以参考TCP的可靠机制

引入序列号 , 保证数据顺序实现去重

引入确认应答

实现超时重传

  • 17
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值