TCP协议浅析TCP概述TCP可靠数据传输TCP流量控制TCP连接管理

本文将简单介绍tcp协议的基本内容,主要包括一下四部分:

  • tcp概述
  • TCP可靠数据传输
  • TCP流量控制
  • TCP连接管理 让我们对tcp有一个简单的回顾总结

TCP概述

  • tcp是一个点对点端到端的传输协议,有一个发送方和接收方。
  • tcp传输的是可靠的按序到达的字节流
  • tcp采用流水线机制,提高传输的效率。TCP通过拥塞控制和流量控制机制来控制滑动窗口的大小
  • tcp协议分别设置了发送方缓存和接收方缓存

Paste_Image.png

  • tcp采取全双工(full-duplex)传输,也就是传输过程中,同一连接可以传输双向的数据流,发送方可以传给接收方,接收方也可以传给发送方。
  • tcp是面向连接的协议,通信双方在发送数据之前必须建立连接。连接状态只在连接的两端中维护,在沿途节点中并不维护状态。TCP连接包括:两台主机上的缓存、连接状态变量、socket等
  • tcp实现了流量控制机制

TCP段结构

Paste_Image.png

TCP: 序列号和ACK

序列号:

  • 序列号指的是segment中第一个字节的编号,而不是segment的编号
  • 建立TCP连接时,双方随机选择序列号

ACKs:

  • 希望接收到的下一个字节的序列号
  • 累计确认:该序列号之前的所有字节均已被正确接收到

Q: 接收方如何处理乱序到达的Segment?

  • A: TCP规范中没有规定,由TCP的实现者做出决策

Paste_Image.png

上图我们进行一个分析,以便搞清楚tcp序列号和ack的应用 首先,hostA作为发送方给B发送数据,随机选择一个序列号seq = 42,也就是这段segment中的第一个字节的编号,并且设置ack=79,这表示,希望接收方回传seg=79作为确认信号代表接收方已经正确接受了这段数据 然后HostB成功接收到数据,想发送方返回确认信息,根据发送方的ack,所以确认的seg=79,然后通过ack告知希望接收到的下一个字节的序列号,并同时表示之前的所有字节均已被正确接收,所以发送ack=43告知已经接收到43号之前的字节,并希望发送方传送43号字节

TCP可靠数据传输

具体的可靠传输原理在上一篇博文中http://www.jianshu.com/p/6a99944bb9fa 接下来我们看看tcp协议是如何实现可靠传输的。

  • TCP在IP层提供的不可靠服务基础上实现可靠数据传输服务
  • 流水线机制
  • 累积确认
  • TCP使用单一重传定时器
  • 触发重传的事件:超时和收到重复ACK

RTT和超时

问题:如何设置定时器的超时时间?

  • 大于RTT, 但是RTT是变化的
  • 过短:不必要的重传
  • 过长: 对段丢失时间反应

问题:如何估计RTT? SampleRTT: 测量从段发出去到收到ACK的时间忽略重传 SampleRTT变化,测量多个SampleRTT,求平均值,形成RTT的估计值EstimatedRTT

EstimatedRTT = (1- )EstimatedRTT + SampleRTT 指数加权移动平均 典型值:0.125

TCP发送方事件

从应用层收到数据后,会进行以下几个步骤:

  • 创建segment
  • 序列号是segment第一个字节的编号
  • 开启计时器
  • 设置超时时间TimeOutInterval

如果发生超时事件:

  • 重传引起超时的segment
  • 重启计时器

收到ACK:

  • 如果确认此前未确认的Segment,更新SendBase,如果窗口中还有未被确认的分组,重新启动定时器

发送端伪码

NextSeqNum = InitialSeqNum
SendBase = InitialSeqNum
loop (forever) {
switch(event)
event: data received from application above
create TCP segment with sequence number NextSeqNum
if (timer currently not running)
start timer
pass segment to IP
NextSeqNum = NextSeqNum + length(data)
event: timer timeout
retransmit not-yet-acknowledged segment with
smallest sequence number
start timer
event: ACK received, with ACK field value of y
if (y > SendBase) {
SendBase = y
if (there are currently not-yet-acknowledged segments)
start timer
}
} /* end of loop forever */

TCP重传示例

Paste_Image.png

Paste_Image.png

Paste_Image.png

快速重传机制

TCP的实现中,如果发生超时,超时时间间隔将重新设置,即将超时时间间隔加倍,导致其很大,重发丢失的分组之前要等待很长时间. 通过重复ACK检测分组丢失,Sender会背靠背地发送多个分组,如果某个分组丢失,可能会引发多个重复的ACK. 如果sender收到对同一数据的3个ACK,则假定该数据之后的段已经丢失. 快速重传:在定时器超时之前即进行重传 算法

event: ACK received, with ACK field value of y
if (y > SendBase) {
SendBase = y
if (there are currently not-yet-acknowledged segments)
start timer
}
else {
increment count of dup ACKs received for y
if (count of dup ACKs received for y = 3) {
resend segment with sequence number y
}

TCP流量控制

接收方为TCP连接分配buffer

Paste_Image.png

上层应用可能处理buffer中数据的速度较慢

流量控制:发送方不会传输的太多、太快以至于淹没接收方(buffer溢出)

(假定TCP receiver丢弃乱序的segments) Buffer中的可用空间(spare room) = RcvWindow = RcvBuffer-[LastByteRcvd -LastByteRead]

Receiver通过在Segment的头部字段将RcvWindow 告诉Sender。 Sender限制自己已经发送的但还未收到ACK的数据不超过接收方的空闲RcvWindow尺寸。

Receiver告知SenderRcvWindow=0,会出现什么情况? 会出现卡死,发送方不发数据了。关于这些问题具体会在tcp拥塞控制里面讨论。

TCP连接管理

TCP sender和receiver在传输数据前需要建立连接。

三次握手机制

Step 1: client host sends TCP SYN segment to server  specifies initial seq #  no data Step 2: server host receives SYN, replies with SYNACK segment  server allocates buffers  specifies server initial seq. # Step 3: client receives SYNACK, replies with ACK segment, which may contain data

Paste_Image.png

四次握手机制

TCP连接管理:关闭

Step 1: client向server发送TCP FIN 控制segment Step 2: server 收到FIN, 回复ACK. 关闭连接, 发送 FIN. Step 3: client 收到FIN, 回复ACK.  进入“等待” –如果收到FIN,会重新发送ACK Step 4: server收到ACK. 连接关闭.

Paste_Image.png

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。  (1) TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送(报文段4)。  (2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。  (3) 服务器关闭客户端的连接,发送一个FIN给客户端(报文段6)。  (4) 客户段发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IT笔记

本地私服仓库nexus3.3.1使用手册

私服架构 私服是指私有服务器,是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构建。有了私服之后,当 Maven 需要下载构件时,直接请求私服...

1.1K7
来自专栏左瞅瞅,右瞅瞅

nmap详解

nmap,也就是Network Mapper,最早是Linux下的网络扫描和嗅探工具包,用来扫描网上电脑开放的网络连接端,确定哪些服务运行在哪些连接端。它是网...

2471
来自专栏Brian

Linux 系统优化

概述 在Linux 学习笔记一大体介绍了一些简单的Linux知识和一些简单的优化。下面我们来学习一下Linux和Linux一些安全知识(Linux是基于内核为...

4426
来自专栏前端开发

前端安全问题之-CSRF攻击

2483
来自专栏xcywt

TCP头部分析与确认号的理解

1、TCP的特点: 基于字节流 面向连接 可靠传输 缓冲传输 全双工 流量控制 2、头部格式和说明 图源百度。如下图示,就是TCP包的头部结构。可以看到这个头部...

32310
来自专栏破晓之歌

webpack项目初始化和基于模块的脚手架搭建

http://localhost:8088/dist/view/index.html

931
来自专栏xcywt

WireShark 使用

1、干货 Wireshark(前称Ethereal)是一个网络封包分析软件。网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料。Wire...

2339
来自专栏韩伟的专栏

状态模式:一个Epoll边缘触发的代理服务器设计

设计模式是一门热门的知识,但是何时应该用哪个,却往往不容易掌握,本文以一个Socks5代理服务器的设计为例,介绍状态模式的实践用法。 软件的功能介绍 提供Soc...

4677
来自专栏linux运维学习

linux学习第二十八篇:监控io性能,free命令,ps命令,查看网络状态,linux下抓包

监控磁盘io性能 (命令:iostat,iotop) 查看磁盘读写状态: iostat -x %util:表示io等待,也就是磁盘使用占用cpu百分比。...

6229
来自专栏运维小白

12.22 php-fpm慢执行日志

php-fpm慢执行日志目录概要 vim /usr/local/php-fpm/etc/php-fpm.d/www.conf//加入如下内容 request_s...

3647

扫码关注云+社区

领取腾讯云代金券