初识TCP

news/2024/5/17 16:56:57 标签: 网络, TCP

TCP -- Transmission Control Protocol

  • 可靠性
  • TCP报头
  • 确认应答(ACK)机制
  • 超时重传
  • 连接管理机制
    • TCP状态转移图
    • 三次握手
    • 四次挥手
      • TIME_WAIT状态
  • 流量控制
  • 拥塞控制
  • TCP细节优化
    • 快重传
    • 延迟应答
    • 捎带应答
  • 面向字节流
  • TCP异常情况

TCP协议和UDP协议是运行在传输层的协议,也是为了结局进程间通信的问题,它相对于UDP协议而言,是一种有连接的,可靠的协议。

可靠性

为什么需要可靠性?
因为网络的不可靠,而应用层很多时候需要可靠的传输(核心)

什么是可靠性?

  • 尽可能的吧数据发送给对方,不丢包
  • 如果实在发送不到,至少通知应用层这个错误
  • 保证数据的有序到达
  • TCP保证不会收的错误的数据(只能保证无意识的错误,不能防范有意识的篡改)

TCP_13">TCP报头

在这里插入图片描述

确认应答(ACK)机制

简单理解,可以理解为TCP发送的数据是有编号的,当接收方收到数据后,有责任进行应答,将期待下一次收到的数据的第一个编号发送回来
例:

在这里插入图片描述
TCP(Segment)既可以当发送使用,也可以当应答使用,互相不冲突
标志位上的ACK就是含有应答的意义(==1是应答,==0不是应答,ASN无效)

超时重传

如果长时间未收到应答,可能发生什么?

  • 数据包可能丢了,对方没有收到。
  • 对方应答了,但应答包丢失

如果超过一定的时间,仍未收到对应应答,则将对应的数据重新进行发送

如果是应答包丢失的情况下,再次发送数据过去,接收方是否可以判断?
可以,TCP内部管理着接收数据的序号,TCP段带有序号
接下来,接收端会将数据丢弃,然后发送应答

如果超时重传后还是没有收到应答怎么办?
多次尝试(有限次数)
1、多次尝试(retry)过程中,超时时间往往越来越长
2、当多次尝试不成功,达到一定阈值时,就会停止发送,同时还会发一个Segment的充值链接,同时通知应用层,(java中会收到一个异常——SocketException:reset by remote peer)

数据编号 + 确认应答 + 超时重传 可以使得数据有序

连接管理机制

为什么需要建立连接?至少能证明对方是在线的。

在正常情况下,TCP都要经过三次握手建立连接,四次挥手断开连接
有了连接管理后,就只能一对一通信了,没办法广播了。

TCP_53">TCP状态转移图

在这里插入图片描述

三次握手

SYN是用作TCP段同步的意义
首先由主动连接方发起一个 SYN,别连接方收到会回复一个ACK,然后被连接方也会发送一个SYN,连接方收到回复ACK
如图:
在这里插入图片描述

也可以理解为:

第一次握手: A给B打电话说,你可以听到我说话吗?
第二次握手: B收到了A的信息,然后对A说: 我可以听得到你说话啊,你能听得到我说话吗?
第三次握手: A收到了B的信息,然后说可以的,我要给你发信息啦!
 在三次握手之后,A和B都能确定这么一件事: 我说的话,你能听到; 你说的话,我也能听到。 这样,就可以开始正常通信了。
 如果两次,那么B无法确定B的信息A是否能收到,所以如果B先说话,可能后面的A都收不到,会出现问题 。
 如果四次,那么就造成了浪费,因为在三次结束之后,就已经可以保证A可以给B发信息,A可以收到B的信息; B可以给A发信息,B可以收到A的信息。

四次挥手

当需要释放连接的时候,至少由一方主动发起,
主动关闭方发送FIN,被关闭方发送ACK,被关闭方发送FIN,主动关闭方发送ACK

在这里插入图片描述
为什么不可以三次挥手呢?

关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了

所以你未必会马上关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

可能有人会有疑问,tcp我握手的时候为何ACK(确认)和SYN(建立连接)是一起发送。挥手的时候为什么是分开的时候发送呢?

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。

但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步挥手。

简单理解四次挥手:
A:“喂,我不说了 (FIN)。”A->FIN_WAIT1
B:“我知道了(ACK)。等下,上一句还没说完。Balabala……(传输数据)”B->CLOSE_WAIT | A->FIN_WAIT2
B:”好了,说完了,我也不说了(FIN)。”B->LAST_ACK
A:”我知道了(ACK)。”A->TIME_WAIT | B->CLOSED
A等待2MSL,保证B收到了消息,否则重说一次”我知道了”,A->CLOSED
这样,通过四次挥手,可以把该说的话都说完,并且A和B都知道自己没话说了,对方也没花说了,然后就挂掉电话(断开链接)了 。

TIME_WAIT状态

TIME_WAIT这个状态出现在主动关闭方,并且持续时间是2 *MSL(Maximum Segment Live)
出现的原因:

  • 最后一个ACK可能会丢失,所以需要保持一段时间
  • 把停止使用的五元组闲置一段时间,保证网络上这条连接的数据全部失效,小概率可能性这个五元组又重新分配了,也保证收到数据一定是新连接
  • 2 * MSL的时间,可以保证 : 对方大概率收到了我们的ACK,网络上所有老连接的包已经失效了,即使五元组在分配,也安全了。

作为开发人员,发现服务器上出现了大量的TIME_WAIT,是不是合理的呢?对服务器有没有影响?如果有影响怎么调增代码结构?

理论上说是合理的。
会有一些影响,连接对象一直存在,关于对象关联下的一系列资源都需要保留(内存)
解决方法:避免我们主动关闭链接

CLOSE_WAIT状态。是被关闭方的状态

一般而言,对于服务器上出现大量的CLOSE_WAIT,原因是服务器没有正确的关闭socket导致四次挥手没有正确的完成,只需要加上对应的close解决问题。

流量控制

根据接收方的接受能力进行发送量控制
接收窗口:接收方告诉发送方自己当前的接收能力
发送窗口:控制发送量
滑动窗口:控制发送量过程中的过程、动作

TCP首部的窗口大小的字段通过ACK机制通知发送端,

TCP发送缓冲区:
例如:在这里插入图片描述

拥塞控制

根据网络拥塞窗口推断出发送量的大小
根据丢包情况,反推网络拥塞情况
没有丢包->100%
在这里插入图片描述
发送量控制 流量控制 + 拥塞控制

TCP_132">TCP细节优化

快重传

数据包不停地向接收方发送(不必等到收到ACK在发送下一个),接收方传递会ACK应答。如果有一个包丢了,那么应答ACK会一直发送下一个应该发送的字节头,当到达一定次数,发送方会重新发送,丢掉的包,收到后返回下一个应该发送的字节头。

延迟应答

可以每N个包应答一次,超过最大的延迟时间就应答一次

捎带应答

非sync包,理论上都可以捎带应答
在延迟应答的基础上我们发现每次发送都是 一发一收,我怕,我们的ACK可以搭顺风车。

面向字节流

TCP超时重传机制 + 发送量控制带来的副作用是:数据只能通过字节流的形式提供给对方
TCP有自己的发送缓冲区和接收缓冲区。

我们要在UDP协议上开发一个可靠的应用层协议,具体怎么做?
具有TCP的特性:
校验和、序列号、确认应答、超时重发、连接管理、流量控制、拥塞控制

TCP_154">TCP异常情况

1、进程终止:进程终止会释放文件描述符,仍然可以发送FIN,和正常关闭一样
2、机器重启:和进程终止一样
机器掉电/网线断开:接收端认为连接还在,一旦接收端有写入操作,接收端发现连接不在了,就会进行reset,TCP自己也内置了一个保活定时器,会定期询问对方是否还在,如果不在也会释放。

  • 只要os有机会介入,os就有能力,将所有的连接进行四次挥手
  • 如果是os没有机会介入的关机,主机B上的进程、连接都没有了
  • 如果处于写数据(发送数据)的状态,当到达充实阈值时,会判断为连接已关闭(异常关闭),通知应用层,SocketException,需要一定时间,不能立即可知
  • 如果处于读数据的状态——确实无法判定
    解决问题思路:
    1、TCP协议层面有一种KeepAlive机制(每隔一段时间,尝试发送个空数据)
    2、应用层方法:read(timeout),如果超时了,尝试写一个数据过去——>心跳包(heartbeat)

http://www.niftyadmin.cn/n/1530222.html

相关文章

顺序表和模拟实现ArrayList的常用方法

模拟实现ArrayList的常用方法ArrayListArrayList:顺序表顺序表和数组的区别:顺序表中的注意点:ArrayList的常用方法模拟实现ArrayList的常用方法ArrayList ArrayList:顺序表 我们可以将顺序表的底层理解成为一个数组&#xff08…

JS实现网页时钟

JS实现网页时钟 1.js获取时间new data var myDate new Date();//获取系统当前时间 myDate.getYear(); //获取当前年份(2位)myDate.getFullYear(); //获取完整的年份(4位,1970-????)myDate.getMonth(); //获取当前月份(0-11,0代表1月)myDate.getDate(); //获取当前日(1-…

JS实现网页飘窗

JS实现网页飘窗 1.在html中设置一个飘窗的div&#xff0c;div中可以添加图片&#xff0c;添加文字通过css展现在飘窗中&#xff1b; <!--飘窗--> <div id"roll"><img src"img/roll.jpg"> </div> 2.在css中对飘窗设置长宽&#…

仿百度搜索框

仿百度搜索框自动补充搜索内容实现过程&#xff1a; 1.设置图片和搜索框两个div <div id"img"><img src"img/baidu.png"> </div> <div id"box"><input type"text" id"textSearch"><inpu…

吞吐量达到瓶颈后下降_无需人工干预,如何找到Kafka集群的吞吐量极限?

作者&#xff5c;Peng Kang 译者&#xff5c;阿拉丁 编辑&#xff5c;Debra AI 前线导读&#xff1a;Kafka 是非常流行的分布式流式处理和大数据消息队列解决方案&#xff0c;在技术行业已经得到了广泛采用&#xff0c;在 Dropbox 也不例外。Kafka 在 Dropbox 的很多分布式系统…

JS实现购物车

JS实现购物车 1.实现思路&#xff1a; &#xff08;1&#xff09;在body中定义一个id"list",将所有商品存放在一个列表中&#xff0c;当进入购物车时如果有两个商品被勾选了&#xff0c;需要计算出总共的价钱和商品的件数以及最贵的商品价格&#xff1b; &#xf…

学什么就业前景好的专业_8大类专业中就业前景好的10个专业,赶紧收藏起来

大学里哪些专业就业前景好、比较“热门”是广大考生和家长朋友们十分关心的问题&#xff0c;但是这么多专业和院校怎么选择呢&#xff1f;其实就业前景好的专业和国家发展现状离不开的&#xff0c;计算机、机械、电气、土木、医学等专业就业都是非常不错的&#xff0c;以下是为…

JS实现页面刷新的方法

1.JS实现普通页面刷新 测试页面&#xff1a; <!DOCTYPE html> <html> <head><title>页面刷新</title> </head> <body><h1 id"text">页面刷新</h1><button onclick"fresh()">刷新</butto…