计算机网络整理(三): 传输层

三. 传输层

1. TCP协议

1.1 什么是TCP协议

TCP(Transmission Control Protocol)传输控制协议,是传输层一种面向连接的,可靠的,基于字节流的协议,用来保证数据的可靠传输.

TCP位于应用层跟网络层之间,保证应用数据成功在网络之间的可靠传输.

TCP并不能保证数据一定会被对方接收到,因为这是不可能的,如果有可能,就把数据传递给对方,实在没办法就放弃重传并且终端连接来通知用户,因此TCP并不是100%可靠的协议,它提供的是数据的可靠递送或故障的可靠通知.

那么TCP是如何保证数据传输的可靠性呢?

1.2 TCP数据包的大小

在这里插入图片描述

一个以太网数据包的大小固定为1522个字节;

1522 = 22(以太网Head) + 20(IP Head) + 20(TCP Head) + 1460(Data)

其中Data大小被称为TCP数据包的负载,因此TCP数据包最大负载是1460个字节,但是由于IP和TCP协议往往有额外的Head信息,所以实际负载在1400字节左右.

1.3 TCP数据包编号

由于TCP一个数据包的负载大小是有限的(1400bit左右),那么一次性发送大量数据,比如10M的文件,就需要分包,为了方便接收方还原或者丢包的时候知道丢失是哪个包,

除了第一个包是随机数以外,后面每个包的编号都是前面一个包的编号+负载大小,比如一号包是1,包的负载是100个字节,那么紧接其后的二号包编号应该是101.为了保证可靠性,每个数据包都有自身编号,和下一个包的编号,这样接收方就可以如链表一般得到一个完整的数据包了,而且一旦数据大小对不上两个包编号的差,就能快速定位问题了.

对于分包组装来说,就是操作系统做的事情了,应用程序拿到的必定是操作系统组装好的完整10M数据包,对于操作系统来说,他做的也就是从第一个数据包开始,如同链表的顺序访问一般,按照下一个数据包编号把所有数据包组合好,然后按照TCP数据包里面的port参数,发给不同的应用程序,比如TCP数据包里面的port是80,而80端口是web服务复制监控的,web服务就会把数据包给到浏览器应用程序.

1.4 慢启动和ACK

服务器发送数据包,当然越快越好,最好一次性全发出去。但是,发得太快,就有可能丢包。带宽小、路由器过热、缓存溢出等许多因素都会导致丢包。线路不好的话,发得越快,丢得越多。

慢启动指的是服务器发送数据包的时候,由于事先不知道线路的理想速率,在刚开始的时候发的较慢,如果不丢包,就加快发送速度,如果丢包就降低发送速度.

Linux 内核里面设定了(常量TCP_INIT_CWND),刚开始通信的时候,发送方一次性发送10个数据包,即"发送窗口"的初始大小为10。然后停下来,等待接收方的确认,再继续发送。

这种慢启动再由线路接受速率的操作是怎么做到的呢? 答案是ACK

默认情况下,接收方每收到两个数据包,就要发送一个确认"ackonwledgement"消息,简称ACK.

ACK携带两个消息

  • 期待收到的下一个数据包的编号(用来告诉服务器自己本包收到了多少数据)
  • 接收方的接收窗口缓存剩余(告诉服务器注意别发太快以免自己接收不过来)

服务器收到ACK信息,就可以推测接收方大概的网速,从而调整发送速率,调整好之后的固定速度,就是"发送窗口"的正常大小,该大小是可变的.

即便接收方带宽再高,TCP也总从10个数据包开始慢慢测试,过一段时间才达到最高传输速率,这就是整个慢启动.

1.5 快重传和快恢复

快重传算法要求接收方每收到一个失序的报文就立即发送重复确认,而不是等到自己发送数据时才确认;

假如正确情况下,接收方应该收到Msg 1~4这四个报文,实际上收到Msg 1,Msg 3,Msg4,当收到Msg3的时候,接收端发现失序,立刻发送Msg1的序列号跟服务器确认,服务器收到立刻恢复到Msg1 开始重传,而不用等到发完四个包再重传,这一机制提高了网络的吞吐量.

1.6 TCP连接建立时的三次握手

模拟情景:

卢本伟: 听得到我说话吗?老,老铁(发出SYN=1,等待确认seq=x)

队友: 听得到(自己听到的消息是ACK=1,SYN=1),你听得见我说话吗(发送Ack=1,seq=y)

卢本伟: 我听得到(ACK=1),兄弟(Seq=x+1,Ack=y+1)

之后卢本伟开始跟队友聊自己的背包平底锅…

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oa9i7ogy-1614233973989)(/Users/dinl/Library/Application Support/typora-user-images/image-20210224173928956.png)]

  1. 客户端向服务器发送SYN=1请求,seq为x(SYN=1表示尝试建立连接)
  2. 服务器收到并同意建立连接(ACK=1),向客户端发送SYN=1(服务器尝试向客户端建立连接),序列号为y,为了表示自己收到了seq,还要回复Ack=seq+1
  3. 客户端同意建立连接(ACK=1),表示收到服务器端的确认号 Ack,并将其值作为自己的序号值(Seq=x+1),还要告诉对方自己收到了对方的序列号(Ack=y+1)

当服务器端收到来自客户端确认收到服务器数据的报文后,得知从服务器到客户端的数据传输是正常的,从而结束 SYN-SEND 阶段,进入 ESTABLISHED 阶段,从而完成三次握手。

常见问题汇总

  1. 第一次握手失败会发生什么?

    服务器没收到SYN=1,则不会做出任何回应,此时客户端请求重连,重连次数超过最大重传次数,会报错返回-1;

  2. 第二次握手失败会发生什么?

    若第二次握手客户端未接收到服务器回应的 ACK 报文时,客户端会采取第一次握手失败时的动作,这里不再重复,而服务器端此时将阻塞在 accept() 系统调用处等待 client 再次发送 ACK 报文

  3. 第三次握手失败会发生什么?

    服务器会跟客户端一样失败重传,若超过重传次数,accept()系统调用返回-1,服务端连接建立失败.

  4. 如果两次握手会怎么样?

    第二次握手后就建立连接的话,此时客户端知道服务器能够正常接收到自己发送的数据,而服务器并不知道客户端是否能够收到自己发送的数据。

1.7 TCP连接关闭时的四次挥手

在这里插入图片描述

  1. 客户端向服务器发起请求(FIN=1)请求断开连接,并发送序列号Seq=u,自身从ESTABLISHED进入FIN-WAIT-1
  2. 服务器收到FIN=1的请求断开连接报文后,结束ESTABLISHED阶段,进入CLOSE-WAIT(等待上层程序确认没有未发的数据)阶段,做好了释放连接准备后,发送报文给客户端,告知对方自己已经收到客户端的关闭连接请求,并让对方再等等,发送报文包括
    • ACK=1,收到客户端的FIN=1请求
    • 确认号为Ack=u+1,表示在已经收到服务器报文的基础上,将其序列号加1作为本段报文确认好Ack的值
    • 序列号为Seq=v
  3. 服务器确认没有未发完的内容之后,向客户端发送请求FIN=1请求断开连接,标记位是1,序列号是w,Ack=u+1
  4. 客户端回复ACK=1表示已经收到,Seq=u+1,将对方的Ack确认消息当做自己的序列号,并且确认号Ack为w+1,然后自己进入TIME-WAIT等待两个MSL((Maximum Segment Lifetime)时间,如果没有收到服务器的消息,则客户端CLOSE,服务器收到此消息之后 也CLOSE连接,至此TCP连接关闭.

2. UDP协议

2.1 什么是UDP协议

UDP(User Datagram Protocol) 用户数据包协议是一种无连接,面向报文的传输协议.与TCP互为补充,UDP不保证传输的可靠性,只尽最大能力交付报文,所以主机不需要维持复杂的连接状态表,除此之外,UDP没有拥塞控制,不会因为网络拥塞,影响服务器的传送速度.

2.2 UDP跟TCP协议的区别
协议是否面向连接传输可靠性传输形式传输效率所需资源头部字节应用场景
TCP可靠字节流慢->稍快20~60文件传输,邮件传输
UDP不可靠数据报文段8即时通信
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值