| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> TCP协议 -> 正文阅读 |
|
[网络协议]TCP协议 |
目录 TCP报文段首部(1)源端口和目的端口:各占2个字节,分别写入源端口号和目的端口号。 (2)序号:占4字节,在一个TCP连接中每一个字节都按顺序编号。整个要传送的字节流的起始序号都必须在连接建立时设置。首部中的序号字段值指的是本报文段发送的数据的第一个字节的序号 (3)确认号:占4字节,是期望收到对方下一个报文段的第一个数据字节的序号。 (4)数据偏移:占4位,实际上指出TCP报文段首部长度。注意是以4字节长的字为计算单位 (5)保留:占6位,今后使用。 (6)紧急URG:当URG=1时,表明紧急指针字段有效。它告诉系统此报文中有紧急数据,应尽快传送,而不要按照原来的排队顺序传送 (7)确认ACK:仅当ACK=1时,确认号字段才有效。 (8)推送PSH:两个进程在进行交互式通信时,一个进程键入一个命令希望另一个进程立即收到该进程的响应,将PSH置为1,TCP使用推送操作,发送方发送一个报文段,接收方收到TCP推送的报文段时,立即向前交付接受应用程序,不等整个缓冲区满了才向上交付。 (9)复位RST:当RST=1时,必须释放连接,然后再重新建立运输连接 (10)同步SYN: (11)终止FIN:用来释放一个连接。当FIN=1时,表明报文段发送方数据已经发送完毕,并要求释放连接 (12)窗口:占2字节,窗口值指的是发送本报文段的一方接收窗口的大小,告诉对方:从本报文段首部的确认序号算起,目前允许对方发送的数据量。 (13)校验和:占2字节。 (14)紧急指针:占2字节。紧急指针仅在URG=1时才有意义,它指出本报文段中紧急数据的字节数。值得注意的是,即使窗口为零,也可以发送紧急数据。 (15)选项:长度可变,最长可达40字节。 TCP连接建立(三次握手)TCP建立连接的过程叫做握手,握手需要在客户端和服务端之间交换三个TCP报文段,如下图: 客户端主动打开连接,而服务端被动打开连接。客户端向服务端发出请求连接报文段,首部中SYN=1,同时选择一个初始序号seq=x。TCP规定,SYN报文段不能携带数据,但是要消耗掉一个序号。同时客户端进入SYN_SENT状态。 服务端在收到连接请求后,如同意建立连接,向客户端发送确认。在确认报文段中应把SYN位和ACK位都置1,同时选择一个一个初始序号seq=y,确认序号是seq=x+1。这个报文段也不能携带数据,但同样要消耗掉一个序号。同时服务端进入SYN_RECV状态。 客户端收到服务端的确认后,还要向服务端给出确认。确认报文段ACK置1,自己的序号seq=x+1,确认序号为ack=y+1。TCP规定,ACK报文段可以携带数据,但如果不携带数据的情况下,下一个报文段的序号仍是seq=x+1,也就是说纯ACK数据包不消耗序号。同时客户端进入ESTABLISHED状态。 当服务端收到客户端的确认后,也进入ESTABLISHED状态。 自此三次握手结束,连接建立成功,为了更直观的看到现象,可以编写客户端与服务端的TCP代码后,使用抓包工具进行抓包,如下图: TCP连接释放(四次挥手)?数据传输完成后,通信双方都可释放连接。A的应用进程先向其TCP发出连接释放报文段,并停止数据发送,主动关闭TCP连接。A把释放报文段首部的终止控制位FIN置1,其序号为seq=u,它等于前面已经传送过的数据的最后一个字节的序号加1。FIN报文段即使不携带数据,也消耗掉一个序号。同时A进入FIN_WAIT_1状态。 B收到连接释放报文段后即发出确认,自己的序号是seq=v,确认号是ack=u+1,然后B就进入CLOSED_WAIT状态。如果此时B要发送数据,A仍要接收,也就是说这个状态可能会持续一段时间。 A在收到B的确认后就进入FIN_WAIT_2状态,等待B发出连接释放报文。 若B已经没有要向A发送的数据,那么应用进程就会通知TCP释放连接。这时B发送的连接释放报文段FIN=1。现假定此报文段的序号为seq=w(在半连接状态,B可能又发送了一些数据),确认序号重复上次的ack=u+1。这时B进入LAST_ACK状态。 A收到B的连接释放报文段后,还必须对此发出确认。在确认报文段中把ACK置1,自己的序号seq=u+1,确认号ack=w+1,然后进入TIME_WAIT状态。注意:现在TCP连接还没有释放掉,必须经过时间等待计时器设置的时间2MSL后(MSL叫做最长报文段寿命,一般为2分钟),A才进入CLOSED状态。 为什么A在TIME_WAIT状态必须等待2MSL的时间呢? 为了保证A发送的最后一个ACK报文段能够到达B。这个ACK可能会丢失,那么B收不到这个ACK,就会重传FIN+ACK报文段,而A就能在2MSL这段时间内收到这个重传的FIN+ACK报文段。接着A重传一次确认,重新启动2MSL计时器。最后,A和B都正常进入到CLOSED状态。如果A在TIME_WAIT状态不等待一段时间,而是在发送完ACK报文段后立即释放连接,那么就无法收到B重传的FIN+ACK报文段,因而就不会再发送一次确认报文段。这样,B就无法按照正常步骤进入CLOSED状态。 除了这个计时器,TCP中还有一个保活计时器,如下: 服务器每收到一次客户数据,就重新设置保活计时器,通常为两个小时,若两个小时都没有收到客户端数据,服务端就向客户端发送一个探测报文段,每隔75秒发送一次,若连续发送10个探测报文段客户端都没有响应,服务端就认为客户端出了故障,就关闭这个连接。 MSS最大报文段长度MSS是每一个TCP报文段中的数据字段的最大长度,双方在三次握手时协商这个值,MSS=min(客户端MSS,服务端MSS)。MSS是为了防止报文长度过大,在网络中数据丢失,引发超时重传机制。 MSS的值也受到数据链路层MTU的影响,MTU是网卡传输数据帧的一个限制,这个值取决于网络传输设备的特性。在Linux下,使用命令ifconfig可以查看这个值: ip_header+tcp_header+MSS<=MTU。? TCP可靠传输确认应答机制发送方发送的消息,接收方要进行确认。接收方通过序号告诉发送方:期望发送方发送下一个序号的数据,也就是说上一个序号之前的数据都收到了。 超时重传机制当发送方发送数据后启动超时重传计时器,当记时时间超过“超时重传时间”之后,还没有收到确认应答,则重传该报文。计算公式如下: 滑动窗口机制滑动窗口机制:允许窗口大小的数据(不需要等待上次确认)发送到网络中,提高数据吞吐量。 窗口大小:指的是不需要等待确认应答,可以继续发送数据包的最大值。如下图: 滑动窗口向前滑动当收到窗口中最早发送数据的确认应答后,窗口向后滑动,如果收到中间分组但没有收到最早分组的确认应答,滑动窗口不滑动。 滑动窗口丢包问题1.接收方分组ACK丢失 当某个分组ACK丢失,可以通过后续分组的确认应答进行确认,发送方不会触发超时重传。 2.发送方数据丢失 数据一定会重传,只不过在在双方按照滑动窗口发送数据的时候,接收方可以通过三次重复确认,触发快重传,也就是说,发送方还没有触发超时重传机制,数据就已经快重传了。如下图: 发送窗口大小发送方发送大量窗口数据被接收方接收之后,接收方tcp缓冲区(网络协议栈的)空间就会急剧减小,发送方就需要减低发送速率,减少发送的数据量。 接收方可以通过tcp报头中的窗口数值告诉发送方自己的接收能力,以便控制发送方发送窗口大小。 0窗口接收方发送窗口大小为0的数据包给对方,称为0号窗口通告,含义:告诉发送方自己接收不了了,发送方应该停止发送。出现这种情况,可能会引发双方互相等待的死锁局面,如何解决这个问题? TCP为每一个连接设有一个持续计时器。只要TCP连接的一方接收到零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个零窗口探测报文,而对方就在确认这个探测报文段时给出现在的窗口值。 滑动窗口优点:在不考虑网络的情况下,可以提高发送的数据量,因为发送的越多,传输的越多。 滑动窗口缺点: 需要防备数据丢失的情况,也就意味着发送方在没有收到确认之前,需要将数据缓存起来(TCP的发送缓冲区)。 拥塞控制机制基于想要探测网络转发能力的需求,TCP还维护了拥塞窗口,是发送方维护的一个状态变量,会根据网络的拥塞程度动态变化,简单的说,网络转发能力好,拥塞窗口大,网络转发能力若,拥塞窗口小。对于发送方而言,发送的数据大小w=min(发送窗口,拥塞窗口)。发送窗口大小取决于接收方的接收能力,拥塞窗口大小取决于网络转发能力。 TCP怎样维护拥塞窗口的大小? 1.慢启动:随着传输轮次的增加,拥塞窗口呈指数增长,当达到慢开始门限,执行拥塞避免算法。 2.拥塞避免:随着传输轮次的增加,拥塞窗口呈线性增长(每次加1MSS),直到发生拥塞(丢包)?。丢失过多报文段时,执行慢开始算法。 3.快恢复:发送方只是丢失个别报文段,则不启动慢开始,而是执行快恢复,计算新的拥塞窗口门限为wind=wind/2,之后执行拥塞避免算法。 如下图: |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 23:48:46- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |