TCP简介
TCP(Transmission Control Protocol) 传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP是一种面向连接(连接导向)的、可靠的基于字节流的传输层通信协议。TCP将用户数据打包成报文段,它发送后启动一个定时器,另一端收到的数据进行确认、对失序的数据重新排序、丢弃重复数据。
TCP把连接作为最基本的对象,每一条TCP连接都有两个端点,这种断点我们叫作套接字(socket),将端口号拼接到IP地址即构成了套接字,例如,若IP地址为192.3.4.16 而端口号为80,那么得到的套接字为192.3.4.16:80。
TCP的特点有:
- TCP是面向连接的运输层协议;
- 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的;
- TCP提供可靠交付的服务;
- TCP提供全双工通信。数据在两个方向上独立的进行传输。因此,连接的每一端必须保持每个方向上的传输数据序号;
- 面向字节流。【面向字节流的含义:虽然应用程序和TCP交互是一次一个数据块,但TCP把应用程序交下来的数据仅仅是一连串的无结构的字节流。】
TCP报文格式图:
TCP报文首部:
1、源端口和目的端口,各占2个字节,分别写入源端口和目的端口;
2、序号,seq序号,sequence number,占4个字节,TCP连接中传送的字节流中的每个字节都按顺序编号,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。例如,一段报文的序号字段值是 301 ,而携带的数据共有100字段,显然下一个报文段(如果还有的话)的数据序号应该从401开始;
3、确认号,ack序号,acknowledge number,占4个字节,是期望收到对方下一个报文的第一个数据字节的序号。例如,B收到了A发送过来的报文,其序列号字段是501,而数据长度是200字节,这表明B正确的收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701;
4、数据偏移,占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远;
5、保留,占6位,保留今后使用,但目前应都位0;
6、标志位:(共6个,即URG、ACK、PSH、RST、SYN、FIN等)
- 紧急URG,当URG=1,表明紧急指针字段有效。告诉系统此报文段中有紧急数据;
- 确认ACK,仅当ACK=1时,确认号字段才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1;
- 推送PSH,当两个应用进程进行交互式通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应,这时候就将PSH=1;
- 复位RST,当RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接;
- 同步SYN,在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1;
- 终止FIN,用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放;
7、窗口,占2字节,指的是通知接收方,发送本报文你需要有多大的空间来接受;
8、检验和,占2字节,校验首部和数据这两部分;
9、紧急指针,占2字节,指出本报文段中的紧急数据的字节数;
10、选项,长度可变,定义一些其他的可选的参数。
需要注意的是:
(a)不要将确认序号ack与标志位中的ACK搞混了。
(b)确认方的确认号码等于发起方的顺序号码加上数字1:ack=seq+1,两端配对。
TCP在传输之前会进行三次沟通,一般称为“三次握手”(Three-Way Handshake),传完数据断开的时候要进行四次沟通,一般称为“四次挥手”。
“三次握手”过程讲解:
首先,TCP服务器 B 进程先创建传输控制块TCB,时刻准备接受客户进程 A 的连接请求,此时服务器 B 就进入了LISTEN(监听)状态。
然后【第一次握手】:TCP客户进程 A 也是先创建传输控制块TCB,然后向服务器 B 发出连接请求报文,这时报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
接着【第二次握手】:TCP服务器 B 收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1(因为已经收到了序列号为x的数据包,准备接收序列号为x+1的包,所以ack=x+1),同时也要为自己初始化一个序列号 seq=y(B告诉A自己的初始序列号)。此时,TCP服务器 B 进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
再然后【第三次握手】:TCP客户进程 A 收到确认后,还要向服务器 B 给出确认。确认报文的ACK=1,ack=y+1(ack=y+1是表示A正准备接收B序列号为y+1的数据包),自己的序列号seq=x+1。此时,TCP连接建立,客户端 A 进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
最后,当服务器 B 收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
为什么A在第三次握手中还要发送一次确认呢?
这主要是为了防止已失效的连接请求报文段突然又传送到了B,B确认后一直长时间等待A发送请求而浪费B的资源。
所谓“已失效的连接请求报文段”是这样产生的:
正常情况是:A发出连接请求,但因连接请求报文丢失而未收到确认。于是A再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接。A共发送了两个连接请求报文段,其中第一个丢失,第二个到达了B。没有“已失效的连接请求报文段”。
现假定出现一种异常情况,即A发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了,以致延误到连接释放以后的某个时间才到达B。本来这是一个早已失效的报文段,但B收到此失效的连接请求报文段后,就误认为是A发出一次新的连接请求;于是B就向A发出确认报文段,同意建立连接。那么,由于现在A并没有发出建立连接的请求,因此不会理睬B的确认,也不会向B发送数据。但B却以为新的运输连接已经建立了,并一直等待A发来数据。这样的话,B的许多资源就这样白白浪费了。
采用三次握手的办法可以防止上述现象的发生。例如在刚才的情况下,A不向B的确认发出确认,B就由于收不到确认,就认为A并没有要求建立连接。
“四次挥手”过程讲解:
所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。
一、如果是一方主动关闭,另一方被动关闭,那么整个流程如下图所示:(下图以客户端主动发起关闭请求为例)
由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。
上图描述的即是如此。挥手过程如下:
(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
二、实际中还会出现同时发起主动关闭的情况,具体流程如下图:
为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
这是因为:在建立连接时,服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,己方ACK和FIN一般都是分开发送给对方:当收到对方的FIN报文时,仅仅表示对方不再发送数据了,但是对方还能接收己方发送过去的数据;己方如果尚未把全部数据都发送给对方,并且己方如果不立即close,还可以继续发送一些数据给对方,发送完毕后才发送FIN报文给对方来表示同意现在关闭连接。
为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?
这是因为虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文。
TCP简介的更多相关文章
- TCP简介(一)
1. TCP如何利用IP达到自己目的 1.1 IP特点 无连接 不可靠 1.2 TCP将应用程序的传输数据分割成合适的数据块 1.3 定时器 1.4 延迟确认 1.5 检验和 1.6 流量控制 2. ...
- 一起学Python:TCP简介
TCP介绍 TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793 ...
- 端口TCP——简介
cmd命令:telnet 如果需要搭建外网可访问的网站,可以顺便勾选HTTP,HTTPS端口:
- TCP那些事
本文是<TCP-IP详解.卷1 协议>的读书笔记 1 TCP简介 TCP提供一种可靠的.面向连接的字节流服务.TCP通过下面的方式来保证服务是可靠的: 应用程序被分隔成TCP认为最适合发送 ...
- 九、Socket之TCP编程
TCP简介 TCP是Transmission Control Protocol(传输控制协议)的简称,是TCP/IP体系中面向连接的运输层协议,在网络中提供全双工的和可靠的服务. TCP最主要的特点: ...
- C#网络程序设计(3)网络传输编程之TCP编程
网络传输编程指基于各种网络协议进行编程,包括TCP编程,UDP编程,P2P编程.本节介绍TCP编程. (1)TCP简介: TCP是TCP/IP体系中最重要的传输层协议,它提供全双工和可 ...
- TCP三次握手与四次分手
TCP简介 首先来看看OSI的七层模型: 我们需要知道TCP工作在网络OSI的七层模型中的第四层--Transport层,IP在第三层--Network层,ARP在第二层--Data Link层:在第 ...
- tcp入门(唐唐的故事)
1,互联网的实现,分成好几层.每一层都有自己的功能,就像建筑物一样,每一层都靠下一层支持.把互联网分成五层,容易让人理解. 2,对这五层的理解(唐唐讲故事): 实体层:目的就是把计算机连接起来,用电气 ...
- 网络传输编程之TCP
网络传输编程之TCP 网络传输编程指基于各种网络协议进行编程,包括TCP编程,UDP编程,P2P编程.本节介绍TCP编程. (1)TCP简介: TCP是TCP/IP体系中最重要的传输层协议 ...
随机推荐
- ajax请求封装的公共方法
/** * post 方法 */ function ajaxPost(url, params, callBack) { ajax(url,params,"post",callBac ...
- SQL Server 数据恢复到指点时间点(完整恢复)
SQL Server 数据恢复到指点时间点(完整恢复) 高文龙关注2人评论944人阅读2017-03-20 12:57:12 SQL Server 数据恢复到指点时间点(完整恢复) 说到数据库恢复,其 ...
- Confluence 6 白名单表达式类型
表达式类型 当添加一个 URL 到白名单列表中的时候,你可以选择采取下面的表达式进行添加. 域名名称(Domain name) 允许 URL 为一个指定的域名. http://www.example. ...
- Confluence 6 配置一个 Confluence 环境
本部分对你 Confluence 的外部设置进行描述.包括有如何配置 Web 服务器,应用服务器,目录和文件等信息—— Confluence 运行所需要的所有环境.有关在服务器内部对配置进行修改的内容 ...
- Confluence 6 你模板中可用的对象
包含宏正文和参数,下面的 Confluence 对象在宏中可用: $body 宏的正文(如果宏有正文的话) String $paramfoo, $parambar, ...$param<name ...
- 四.awk、sde深度讲解
###sed### 查询 1创建测试文件 cat>person.txt<<EOF> 101,oldboy,CEO> 102,zhangyao,CTO> 103,Al ...
- Saruman's Army(POJ3069)
Description Saruman the White must lead his army along a straight path from Isengard to Helm’s Deep. ...
- Python基础之模块与包
一.模块 1.什么是模块? 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 2.为何要使用模块? 如果你退出python解释器然后重新进入,那么你之前定义的函 ...
- meter压力测试 设置一秒发送一次请求,一秒两次请求
使用jmeter进行压力测试 ,测试情况有 1.一秒钟投1次请求(一个线程) 持续30分钟的情况 2.一秒钟发送2次请求(两个线程) 持续30分钟的情况 下面说一下如何使用jmeter 测试这两种情 ...
- K8s-Pod控制器
在K8s-Pod文档中我们创建的Pod是非托管的Pod,因为Pod被设计为用后就弃的对象,如果Pod正常关闭,K8s会将该Pod清除,它没有自愈的能力.Pod控制器是用来保持Pod状态的一种对象资 ...