3.5 面向连接的运输:TCP
3.5 面向连接的运输:TCP
3.5.1 TCP连接
TCP进行传输之间要进行三次握手建立连接,这个连接不是物理意义上的有一根电线连接,而是应用端两个应用,在逻辑上是已经建立连接了。
TCP 不需要传输的时候会进行四次挥手断开连接。
持续连接:在传输过程中一直保持连接,直到没有数据可以传输。
非持续连接:指传输完一组数据就断开连接,在传输就要建立新的连接。
3.5.2 TCP报文段结构
|
源端口号 |
目的端口号 |
|||||||
|
序号 |
||||||||
|
确认号 |
||||||||
|
首部长度 |
保留未用 |
URG |
ACK |
PSH |
RST |
SYN |
FIN |
接收窗口 |
|
因特网检验和 |
紧急数据指针 |
|||||||
|
选项 |
||||||||
|
数据 |
||||||||
源端口号,目的端口号:略
序号:就是第一个字节的序号,例如总共1000位,成2个报文段,第一个报文段序号是0, 第二个报文段序号是500
确认号:表示N之前的字段全部接收到了
首部长度:4比特,通常首部长度20个字节。20 * 8bit,本来应该是24个字节,但是选 项字段一般为空,所以就是20个字节。
URG:标记是否紧急
ACK:确认bit
PSH:被标记,表示接收方应该立即提交给上层数据
RST,SYN,FIN:用于连接的创建和拆除,RST表示连接重置,SYN表示建立连接,FIN表示关闭连接
接收窗口:用于流量控制,表示接收方愿意接受的字节数量
因特网检验和:用于差错检验
紧急数据指针:指出紧急数据的最后一个字节
3.5.4 可靠数据传输
TCP在IP不可靠的尽力而为服务商创建里一种可靠数据传输服务。
TCP保证从接收缓存中都取出来的数据都是无损坏,无间隔,非冗余,按序的数据流。
一些有趣的情况
第一种情况:
A的报文段序号是92,向B发送了8个字节,那么B应该向A传输ACK(100)表示100以前的报文段收到了,但是B的确认报文丢了,那么A就以为B没收到,所以A就又重现发送了一边数据,造成了数据冗余。
第二种情况:
A连续发送两个报文段给B,第一个报文段序号是92,发送了8个字节,第二个报文段序号是100,发送了20个字节,都完好无损的到达了B,那么第一个报文段的确认号应该是100,第二个应该是120,假设两个回传的确认报文都超时了,A就以为B没收到,所以重传,当A重传序号92的报文段并重启定时器,此时第二个报文(120)的确认报文到了,那么第二个报文就不会被重传。
第三种情况:
和第二种情况一样,在准备重传的时候,第二个报文的确认报文到了,那么两个报文都不会被重传。
超时间隔加倍
实际上就是超时之后,扩大了确认超时的限制。
快速重传
像前面说到的,如果等不到确认报文才开始准备重传,这样会大大增加时延。
快速重传采取的判断丢包的措施是:
如果接收方收到三个冗余ACK(N)即判断丢包了,就立即重传第一个没被确认的报文。
原因:假设A向B发送 n – 1, n, n + 1, n + 2,并且已经收到n – 1
不丢包的情况:
B接收报文的顺序有以下可能:
n – 1, n, n + 1, n + 2;
A收到1次ACK(n);
n – 1, n, n + 1, n + 2;
A收到1次ACK(n);
n – 1, n + 1, n, n + 2
A收到两次ACK(n);
n – 1, n + 1, n + 2, n
A收到三次ACK(n);
n – 1, n + 2, n, n + 1
A收到两次ACK(n);
n – 1, n + 2, n + 1, n
A收到三次ACK(n);
抛去第一种按序到达,乱序到达并且收到3次ACK(n)的概率是2 / 5 = 40%
然后是丢包的情况:
不管什么顺序到达,都会收到3次ACK(n),概率是100%;
虽然收到三次ACK(n)不一定是丢包造成的,但是丢包一定会收到三次ACK(n),两次可能是乱序造成的,三次可能是丢包造成的,四次更可能是丢包造成的但是时延太多,所以就取三次。
是回退N步(GBK)还是选择重传(SR):
TCP作为GBK和SR的混合体,视情况选择两种协议
3.5.5流量控制
接收方维护一个接收窗口(rwnd)的变量来提供流量控制。
假设A通过一条TCP连接,向B发送一个大文件,那么B会为此次连接分配一个缓存,用RcvBuffer表示。
定义两个变量:
LastByteRead:表示应用程序从缓存中读取的最后一个字节的编号
LastByteRcvd:表示接收到数据的最后一个编号
灰色:表示已经读取的部分
深灰色:表示已经缓存,但是没有读取的元素
那么LastByteRead就是A所在的位置,LastByteRcvd就是B所在的位置。
由于TCP不允许缓存溢出,所以LastByteRcvd – LastByteRead <= RcvBuffer。接收窗口那么就只能接收剩余空间了,rwnd <= RcvBuffer – (LastByteRcvd – LastByteRead)。
因此rwnd是进行动态维护的。
还有一个小问题:
假设B的缓存已经满了,即rwnd = 0,所以B的应用程序要清空缓存,但是A并
不知道B有了新的缓存了,所以不会再发送数据,就造成了拥塞。为了解决这个问题,
TCP规范中要求:当主机B接收窗口为0的时候,主机A继续发送一个只含1个字节 的报文段,这个字节被B接收,并清空缓存。
UDP是不提供流量控制的,UDP通常将数据添加到相应套接字“前面”的一个有限大小的缓存中,如果进程读取的不够快,那么缓存就会溢出,并且将丢失报文段。
3.5.6TCP连接
三次握手建立连接:
A想向B传输可靠数据,所以要向B建立一条TCP连接。
- A向B发送一个特殊的TCP报文,SYN字段被置1表示要建立连接,称为SYN报文段,然后随机选择一个初始序列号(client_isn),放在SYN报文段的序号字段中。封装到IP数据报中,并发送给B。
- B收到来自A的SYN报文段,为TCP分配缓存和变量,并向A发送SYN报文,确认号为client_isn + 1 ,并且随机选择一个初始序列号(server_isn)放到SYN报文段的序列号字段。
注意前两次报文都是不携带应用数据的。
3. A收到B的确认报文(,此时已经建立连接),A为TCP分配缓存和变量,然后再给B发送一个报文,SYN标志位置0,确认字段为server_isn + 1。
客户端TCP状态序列:

初始TCP客户端处于CLOSED状态。
打开连接:
①:客户的应用程序发起一个新的TCP连接,引起客户中的TCP向服务器中的TCP发送一个SYN报文段,然后客户端进入SYN_SENT状态
②:收到服务器发来的ACK确认报文段之后进入ESTABLISHED状态(建立连接),此时TCP客户就能发送和接受包含有效载荷数据的TCP报文段了
关闭连接:
③:客户端TCP发送一个带有FIN标置为1的报文段,客户端进入FIN_WAIT_1状态。
④:客户端收到服务器发送的ACK确认报文段,客户端进入FIN_WAIT_2状态。
⑤:当客户端处于FIN_WAIT_2状态时,客户端等待服务器发送的FIN报文段,收到FIN报文段,确认后,并进入TIME_WAIT。
⑥:如果ACK报文丢失,那么TIME_WAIT状态会使TCP客户端重传最后的确认报文段
最后连接正式关闭,客户端所有资源被释放。
为什么要三次握手,两次已经建立连接了,为什么还要第三次?
谢仁希《计算机网络》看到的,为了防止已经失效的连接请求报文突然传到服务端造成错误,例如一个第一次握手的报文因为拥塞或者各种原因超时了,即发送端发送了另外的请求报文,那么超时的这个报文就失效了,如果这个报文又传到了服务端,如果只经过两次握手的话,那么就可以建立连接,但是这个连接是不需要的,所以就造成了浪费。
四次挥手释放连接:
- 首先发送方给接收方发送报文并且FIN置1。
- 当接收方收到报文,返回ACK确认报文。
- 接收方再发送一个报文FIN置1
- 接收方收到发送方的ACK确认报文
- 用于此次连接的所有资源被释放
服务器端TCO状态序列:

建立连接:
① :服务器应用程序创建一个监听套接字,进入LISTEN状态
② :接收SYN并且发送SYN&ACK进入SYN_RVCD的状态
③ :接收ACK,等待发送方的数据,进入ESTABLISHED状态
释放链接:
④ :接收FIN发送ACK,进入CLOSE_WAIT状态
⑤ :发送FIN,进入LAST_ACK状态
⑥ :接收ACK不发送,关闭连接
为什么进行四次挥手?
TCP是双工通信,一方收到FIN报文的时候,只是说明没有接收的报文了,还是可以发送的,一方发送了FIN报文,处于FIN_wait1状态,但收到对方确认的ACK报文的时候进入FIN_wait2状态,此时处于半断开。因为是双工通信,所以可能一方想断开,但是另一方还有数据要传输,要等一会在断开,所以进行四次挥手。
3.5 面向连接的运输:TCP的更多相关文章
- 第五节 面向连接传输:TCP
第五节 面向连接传输:TCP TCP概述RFCs:793,1122,1323,2018,2581 点对点: 一个发送方,一个接收方 可靠,按序的字节流: 无“报文边界”,无结构但有 ...
- 面向连接的传输TCP(一)
这篇博客主要是对计算机网络自顶向上做的阅读笔记,深入地了解TCP 一.TCP连接 1.特点: a.TCP是面向连接的,因为一个进程在向另一个进程进行数据传输之前必须先要握手,即要互相发送报文,以确认信 ...
- 计算机网络自顶向下方法第3章-传输层 (Transport Layer).2
3.5 面向连接的运输: TCP 3.5.1 TCP连接 TCP是因特网运输层的面向连接的可靠的运输协议. TCP连接提供全双工服务(full-duplex service). TCP连接是点对点的连 ...
- 《计算机网络》课程笔记 (Ch03-运输层)
为运行在不同主机上的应用进程之间提供逻辑通信功能. 将应用层报文切分为块,然后加上运输层首部,形成报文段,交付给网络层. 多路复用与多路分解 将网络层提供的主机到主机交付服务延伸到进程到进程交付服务. ...
- 无连接运输的UDP、可靠数据传输原理、面向连接运输的TCP
由[RFC 768]定义的UDP只是做了运输协议能够做的最少工作.除了复用/分解功能极少量的差错检测外,它几乎没有对IP增加别的东西.如果应用程序开发人员选择UDP而不是TCP,则该应用程序差不多就是 ...
- 计算机网络及TCP/IP知识点(全面,慢慢看)
TCP/IP网络知识点总结 一.总述 1.定义:计算机网络是一些互相连接的.自治的计算机的集合.因特网是网络的网络. 2.分类: 根据作用范围分类: 广域网 WAN (Wide Area Networ ...
- ACE_linux:TCP通信
1.涉及类 ACE_INET_Addr//ACE网络地址ACE_SOCK_Acceptor//ACE网络服务器ACE_SOCK_Connector//ACE网络客户端ACE_SOCK_Stream// ...
- 计算机网络之TCP协议与UDP协议
运输层向它上面应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最底层. 两个主机进行通信实际上就是两个主机中的应用进程互相通信.应用进程之间的通信又称为端到端的通信. 应用层不同进 ...
- 计算机网络Web应用层与运输层(HTTP/TCP)
应用层协议原理 Web和HTTP DNS:英特网的目录服务 运输层 面向连接的运输:TCP及拥塞原理 一.应用层协议原理 DNS域名解析: (用例:www.baidu.com)域名解析是网络请求的第一 ...
随机推荐
- Arduino 101/Genuino101使用-第一篇
1. 函数API说明文档在哪里? 2. 如果我想定义一个引脚做GPIO,不是库里有的. 3. digitalWrite(13, lighting); 这个函数里面 13代表的是啥? 4. setup( ...
- php编程知识点2018
一 .PHP基础部分 1.PHP语言的一大优势是跨平台,什么是跨平台? PHP的运行环境最优搭配为Apache+MySQL+PHP,此运行环境可以在不同操作系统(例如windows.Linux等)上配 ...
- Flutter系列博文链接
Flutter系列博文链接 ↓: Flutter基础篇: Flutter基础篇(1)-- 跨平台开发框架和工具集锦 Flutter基础篇(2)-- 老司机用一篇博客带你快速熟悉Dart语法 Flutt ...
- 一步步带你配置IIS(包括错误分析)
今天趁着工作中的问题一下子来解决IIS配置 发布网站:点击VS发布网站 第一步:新建配置文件(我取名为webSite) : 第二步:选择发布方法并且选择把文件发布到哪里(比喻在D盘创建一个文件夹web ...
- MySQL数据库--连接
MySQL数据库的概念: MySQL数据库,包括客户端和服务端.客户端就是操作数据库的终端(命令行.navicat),服务端就是安装有MySQL软件的主机(本机或者服务器),MySQL数据库的端口一般 ...
- Android 测试 之MonkeyRunner
一.什么是MonkeyRunner monkeyrunner工具提供了一个API,使用此API写出的程序可以在Android代码之外控制Android设备和模拟器.通过monkeyrunner,您可以 ...
- [Ubuntu] <uptime>命令
uptime 命令 就是查看系统启动时间的,前几个大家应该都很熟悉:当前时间.系统启动时间.正在登陆的用户数 最后的三个数字,分别代表过去 1分钟 5分钟 15分钟 的平均负载(Load Ave ...
- Siki_Unity_2-4_UGUI_Unity5.1 UI 案例学习
Unity 2-4 UGUI Unity5.1 UI 案例学习 任务1-1:UGUI简介 什么是GUI: 游戏的开始菜单 RPG游戏的菜单栏.侧边栏和功能栏(比如背包系统.任务列表等) 设计用来控制移 ...
- docker简单使用+django+uwsgi+nginx项目部署
使用docker 搭建 centos7 环境: 主机环境:windows 10专业版 一.安装docker Hub.docker.com官网下载 docker for windows 安装完成后,任务 ...
- WEB前端开发流程总结
作者声明:本博客中所写的文章,都是博主自学过程的笔记,参考了很多的学习资料,学习资料和笔记会注明出处,所有的内容都以交流学习为主.有不正确的地方,欢迎批评指正 WEB前端开发项目流程总结 1.新建项目 ...