TCP协议数据格式

TCP协议在互联网ISO协议的传输层。

在互联网传输过程中,互联网包在数据链路层,是传输数据的最基础的包。一个互联网的包包含IP包,即互联网包 = 互联网信息包头(至少20字节)+IP包(1480字节) = 数据包1500字节

IP包是跨局域网传输需要路由的包,是处于网络层的包。一个IP包包含一个TCP或UDP的包,即IP包 = IP包头(至少20个字节)+TCP包(1460字节)= 数据包1480字节

TCP包是传输到指定端口的包,每个端口都表示不同的应用协议服务,TCP协议指定了端口,才能解析数据内容,例如http协议就是8080端口解析的。TCP包处于传输层。一个TCP包 =

TCP包头(至少20字节)+HTTP包(1440字节) = 1460字节。

所以一个TCP包的信息内容在1400字节左右,如果TCP的内容数据是1500字节,发送方就需要发送两个TCP包。HTTP协议因此缩短了HTTP包头,让一个HTTP包只需要一个TCP包传输。

例如一个10M的信息,需要发送7489个数据包。

TCP包的包头信息

TCP协议为了保证数据包之间按照顺序发送,每个TCP包都有一个编号,如上10M的信息需要的包里有1-7489的编号。

每一个TCP包头,传递的信息有三个。

一是编号,表示TCP当前的包所在的顺序,也是唯一标识。

二是发送方需要的下一个数据包的编号,表示接收方回复的TCP数据包中的编号是发送方请求的下一个数据包的编号。所以,在接受方丢失了这个包后,发送给对方的请求编号

便不是发送方请求的包编号。

          

例如  A 端------------------------------------TCP(id =1 ,ack = 100,length = 100kb)-----------------------------------------------》 B端  ACK = 1

 A 端------------------------------------TCP(id =101 ,ack = 200, length = 50kb)---------------------------------------------》(包丢失) B端 ACK = 101

      A 端------------------------------------TCP(id =151, ack = 300,length = 100kb)---------------------------------------------》 B端 ACK = 101

A 端的发送窗口=3,即一次性发送3个数据包,第二个数据没有收到,所以B端的ACK不会改变。所以TCP的A端会收到相同的ACK 请求。

  A 端 《---------------------------------TCP(id = 100,ack = 101, length = 100kb)--------------------------------------------   B端

A 端 《---------------------------------TCP(id = 300,ack = 101, length = 100kb)--------------------------------------------   B端

这样A端会堆积很多重复的ACK,当ACK重复三次后,A端会重新发送丢失的包。

    A 端------------------------------------TCP(id =101 , ack = 200, length = 50kb)---------------------------------------------》 B端 ACK = 151

      A 端------------------------------------TCP(id =151 , ack = 300,length = 100kb)---------------------------------------------》 B端 ACK = 251

因此,TCP可以保证包不会丢失。

TCP的传输过程

举一个例子:

     A 端  ------------------------------------TCP(id =1 ,ack = 101,length = 100kb)-----------------------------------------------》 B端  ACK = 1

A 端 《---------------------------------TCP(id = 101,ack = 101, length = 100kb)------------------------------------------------   B端

 A 端   ------------------------------------TCP(id =101 ,ack = 201, length = 50kb)-----------------------------------------------》 B端 ACK = 101

     A 端 《---------------------------------TCP(id = 201,ack = 151, length = 100kb)-------------------------------------------------   B端

   A 端   ------------------------------------TCP(id =151, ack = 301,length = 100kb)---------------------------------------------》 B端 ACK = 101

A 端 《---------------------------------TCP(id = 301,ack = 251, length = 100kb)--------------------------------------------------   B端

     第一条数据包 A端发送给B端的数据编号为1,长度是100字节,第二条数据B端回复A端发送101编号的数据,因此第三A端发送的数据是101开头,且50字节的编号,

第四条数据包 B端再次请求A端给我后续151开头的数据。第五条数据包中A端果然发送给151开头大小为100字节的数据了。最后B端ACK请求251开头的数据。

ACK是什么       

 在LINUX中,每当发送方发送10个数据包后,会停下来等待接收方的确认。一般接收方每接到2个数据包会发送一个确认消息 Acknowledgment 即为ACK,是确认的意思。

ACK里面包含两个消息:

一是期待接收下一个数据包的编号。

二是接收方的接收窗口的剩余容量。

 当发送方获取到这两个信息后,就会知道下一个发送的数据以及发送的数据包的大小,即发送速率。

 例如

 Client ----------------Segment(seqNum = 300,length = 100)--------------->Server

Client   <--------------Acknowledgment(Acknum = 401,Window=60)------>Server

 Client ----------------Segment(seqNum = 401,length = 60)--------------->Server

Client   <--------------Acknowledgment(Acknum = 461,Window=80)------>Server

 Client ----------------Segment(seqNum = 541,length = 100)--------------->Server

Client   <--------------Acknowledgment(Acknum = 641,Window=60)------>Server

因为TCP通信是双方的,所以ACK数据是双方都发送的,所以双方的发送窗口大小不同。而且ACK的字段很小,通常和数据包合并在一起发送。

慢启动

在网络传输过程中,最理想的情况当然是传的越快越好,最好一次性发出去。但是网络的情况不稳定,有可能出现低带宽、路由过热、内存溢出的情况,导致丢包。

线路不好的情况下,发的越快,丢的越多。

所以最理想的情况是在线路允许的情况下,达到最高速率。

但是我们如何知道在什么情况下才是理想的速率呢?答案是慢慢试。

TCP协议为了做到效率和可靠性的统一,设计了一个慢启动的机制。

开始的时候,发送的慢,然后根据丢包的概率,调整速率:如果不丢包,就加快发送速率,如果丢包,就降低发送速率.

一般最开始时一次性发送10个数据包.即发送窗口 = 10.

通过ACK机制发现丢包率,进而实现慢启动机制的设计.

TCP数据包的组装

TCP的数据包传输到接收方后,组装还是由原装操作系统完成的.对于应用程序而言,不关心实现网络通信的细节.除非线路异常,收到的数据总是完整的.

应用程序需要的数据放在TCP数据包里,有自己完整的格式.

TCP并没有完整的协议来标识数据的大小,这由应用层的协议来规定,例如HTTP协议就有一个头信息Content-Length,表示信息体的大小.对于操作系统来说,

就是持续的组装数据包,按照顺序排列好,一个包都不能少.

操作系统不会去处理TCP包里面的数据,一旦组装好TCP数据包,就把它转交给应用程序,TCP数据包里有一个端口参数,就是用来转交给指定的应用程序的.

系统根据TCP数据包里的端口,将组装好的数据转交给应用程序,应用程序收到组装好的原始数据,以浏览器为例,就会根据HTTP协议里的Content-Length字段

正确读取一段段的数据.

TCP数据包编号(SEQ)

一段数据量很大的数据,需要用许多TCP包,例如一个10M的信息,需要7348个TCP数据包才能传输完.为了确认每一个TCP包传送成功,TCP数据包设计了数据包编号(SEQ),

数据包编号是一串随机数字,作为丢包的唯一标识.

最新文章

  1. windows耳机没有声音
  2. C#的Socket实现UDP协议通信
  3. HTML 标签 表格
  4. 定制Eclipse IDE之杂症篇
  5. MySql中的tinying,smallint,int,bigint的类型介绍——转载
  6. spring jdbcTemplate query
  7. MySQL里面的子查询实例
  8. php 面向对象的方式访问数据库
  9. 【BZOJ】【1016】【JSOI2008】最小生成树计数
  10. iOS 抓取 UIwebview 上 所有 图片 并进行滚动播放
  11. eclipse安装反编译插件
  12. 仿360手机卫士界面效果android版源码
  13. 如何让Windows程序只运行一个程序实例?
  14. [html5] canvas 绘图:八卦图
  15. 1. React介绍 React开发环境搭建 React第一个程序
  16. Xamarin 学习笔记 - 配置环境(Windows &amp; iOS)
  17. pthread_cond_wait() 函数的使用
  18. 未来Linux系统将是运维行业必备的技能之一
  19. 用MFC库函数AfxBeginThread()来创建线程
  20. AngularJS实战之ngAnimate插件实现轮播

热门文章

  1. SpringBoot:使用Jenkins自动部署SpringBoot项目(二)具体配置
  2. 【XR-4】题
  3. 【Beta】Scrum Meeting 7 &amp; 与助教谈话
  4. Guava 库
  5. mestasploit笔记 :MS17-010
  6. 洛谷 P1969 积木大赛(NOIP2013)
  7. RockBrain USB Server外设虚拟化高可用解决方案(银企直联虚拟化解决方案)
  8. Nginx的configure脚本支持选项整理
  9. svn 清除用户名和密码
  10. Flutter的Padding、Raw、Column、Expanded组件的基本使用