科普网站建设方案,深圳网站制作哪家便宜,北京网站制作团队,扶贫网站建设的意义目录
1.区别
1.1 概括
1.2 详解
2.TCP
2.1 内容
2.2 可靠传输
2.2.1 确认应答
2.2.2 超时重传
2.2.3 连接管理
三次握手
四次挥手
2.2.4 滑动窗口
2.2.5 流量控制
2.2.6 拥塞控制
2.2.7 延时应答
2.2.8 捎带应答
2.2.9 面向字节流
2.2.10 异常情况的处理
1.…目录
1.区别
1.1 概括
1.2 详解
2.TCP
2.1 内容
2.2 可靠传输
2.2.1 确认应答
2.2.2 超时重传
2.2.3 连接管理
三次握手
四次挥手
2.2.4 滑动窗口
2.2.5 流量控制
2.2.6 拥塞控制
2.2.7 延时应答
2.2.8 捎带应答
2.2.9 面向字节流
2.2.10 异常情况的处理
1.进程崩溃
2.主机关机正常关机
3.主机掉电非正常
4.网线断开
3.对比 TCP和UDP是传输层的两个重要协议也是面试中经常会被问到的属于面试高频点。今天我们来学习这两个协议。
1.区别
1.1 概括
TCP有连接可靠传输面向字节流全双工
UDP无连接不可靠面向数据报全双工
1.2 详解
1.TCP是有连接的UDP是无连接的
连接是抽象的概念本质上是建立连接的双方各自保存对方的信息
两台计算机建立连接就是彼此保存了对方的关键信息
TCP想要通信就需要建立连接做完之后才能后续通信。至于连接如何建立不需要代码干预是系统内核自动负责完成的。
对于应用程序来说客户端这边主要是要发起“建立连接”动作服务器这边主要是把建立好的连接从内核中拿到应用程序里~
如果有客户端和服务器建立连接这个时候服务器的应用程序是不需要做出任何操作也没有任何感知的内核直接就完成了建立连接的过程三次握手完成流程之后就会在内核的队列中这个队列是每个serverSocket都有一个这样的队列排队。
应用程序要想和这个客户端进行通信就需要通过一个accept方法把内核队列已经建立好的连接对象拿到应用程序中。
即一个典型的生产者-消费者模型。
UDP想要通信直接发送数据即可不需要征得对方同意UDP自身也不会保存对方的信息
2.TCP是可靠传输UDP是不可靠传输的
网络上进行通信A- B发送一个消息这个消息是不可能做到100%送到的
TCP就内置了可靠传输机制UDP就没有内置可靠传输。
A - B 发消息消息是不是到达B这一方A自己能感知到进一步的就可以在发送失败的时候采取一定的措施尝试重传之类的
可靠传输需要付出代价a.机制更复杂 b.传输效率会降低
3.TCP是面向字节流的UDP是面向数据报的
TCP和文件一样以字节位单位来进行传输
UDP则是按照数据报为单位来进行传输的UDP数据报是有严格的格式的
4.TCP和UDP都是全双工的
一个信道允许双向通信就是全双工
一个信道允许单向通信就是半双工
2.TCP
2.1 内容 2.2 可靠传输
常见面试题
TCP是如何保证可靠传输的
通过确认应答为核心借助其他机制辅助最终完成可靠传输
2.2.1 确认应答
发送方把数据发给接收方之后接收方收到数据就会给发送方返回一个应答报文
发送方如果收到这个应答报文了就知道自己的数据是否发送成功 2.2.2 超时重传
如果网络传输过程中出现丢包了发送包势必就无法收到ACK了
由于丢包是一个“随机”的事件因此在TCP传输过程中丢包就存在两种情况
1.传输的数据丢了 2.返回的ACK丢了 无论出现上述两种情况发送方都会采取统一的措施就是“重传”
发送方何时重传等待时间
发送方发出数据之后会等待一段时间如果这个时间之内ack来了此时就自然视为数据到达
如果达到这个时间之后数据还没到就会触发重传机制~
超过等待时间再重传~
第二次重传后的等待时间会比第一次时间延长但延长也不是无限制延长重传若干次后时间拉长到一定程度认为数据再重传也没有用了就放弃tcp连接准确来说就是会触发tcp的重置连接操作
TCP会有一个“接收缓冲区”就是一个内存空间会保存当前已经收到的数据以及数据的序号
接收方如果发现当前发送方发来的数据是已经再接收缓冲区中存在的收到过的重复数据了接收方就会直接把这个后来的数据给丢弃掉确保应用程序进行read的时候读到的是只有一个数据
2.2.3 连接管理
建立连接 断开连接
面试中最经典的问题三次握手 四次挥手
建立连接
三次握手
tcp这里的握手也就是给对方传输一个简短的没有业务数据的数据包通过这个数据包来唤起对方的注意从而触发后续的操作握手这个操作不是TCP独有的甚至不是网络通信独有的计算机中很多的操作都会涉及到握手
TCP的三次握手TCP在建立连接的过程中需要通信双方进行“打三次招呼”才能够完成连接建立的 问三次握手是要解决什么问题
答三次握手核心作用一
投石问路确认当前网络是否是畅通的
三次握手核心作用二
能够发送方和接受党都能确认自己的接收能力和发送能力均正常
三次握手核心作用三
让通信双方在通信过程中针对一些重要的参数进行协商
问四次握手可以吗两次握手可以吗
答四次可以但没必要
两次不可以不能达到双方都知道信息的过程 断开连接
四次挥手 为什么中间两次不能像建立连接一样合并为一步
不一定
不能合并的原因ACK和第二个FIN的触发时机是不同的
ACK是内核响应的B收到FIN就会立即返回ACK
第二个FIN是应用程序的代码触发B这边调用了close方法才会触发FIN
是否意味着如果这这边代码close没写/没执行到是不是第二个FIN就一直发不出去有可能的
如果是正常的四次挥手正常的流程断开的连接
如果是不正常的挥手没有挥完四次异常的流程断开连接也是存在的
三次握手ACK和第二个syn都是内核触发的同一个时机可以合并
可以合并的情况TCP还有一个机制延迟应答能够拖延ACK的回应时间一旦ACK滞后了就有机会和下一个FIN一起合并 哪一方主动断开连接哪一方就会进入TIME_WAIT
TIME_WAIT状态的主要存在的意义就是为了防止最后一个ACK丢失留下的后手
如果最后一个ACK丢了站在B的角度B就会触发超时重传重新把刚才的FIN给传一遍
如果刚才A没有TIME_WAIT状态就意味着A这个时候就已经真的释放连接了此时重传的FIN也就没人能处理没人能返回ACK了B也就永远收不到ACK了
A这边使用TIME_WAIT状态进行等待等待的这个时间就会为了处理后续B重传的FIN
此时如果有重传的FIN来了就可以继续返回ACK了B这边的重传才有意义
TIME_WAIT等待多久呢
假设网络上两个节点通信消耗的最大等待时间为MSL此时的TIME_WAIT的时间就是2MSL (已经是上限了绝大部分的数据包不会达)
2.2.4 滑动窗口
提高效率
TCP的可靠传输是会影响传输的效率的
滑动窗口就让可靠传输性能的影响更小一些
TCP只要引入了可靠传输传输效率是不可能超过没有可靠性的UDP的
TCP这里的“效率机制”都是为了让影响更小缩小和UDP的差距 批量传输数据不等ack回来直接再发下一个数据
批量传输也不是“无限的”传输
批量传输也是存在一定的上限的达到上限之后再统一等待ack
不等待的情况批量最所发多少数据这个数据量称为“窗口大小” 当前A-B是批量的发了四份数据
此时B也要给A回应四组ACK此时A已经达到窗口大小再收到ACK之前不能继续往下发了
需要等待有ACK回来了之后才能继续往下发。
可以不需要一次等待四个ACK全部回来之后才能继续发而是回来一个ack就立即继续发一个
窗口越大等待的ack越多此时传输效率也就越高 情况一ack丢了
这种情况不需要任何重传没事了 确认信号表示的含义是当前序号之前的数据已经确认收到了
下一个你应该从确认序号这里继续发送
例如:如果1001这个ACK丢了但是2001ACK到了则证明2001之前的数据都已经确认传输成功了涵盖了1001的情况 情况二数据包丢了 主机A就需要知道是哪个数据丢了主机B也就得告诉A是哪个数据丢了。
主机A看到了B这边连续的几个ack都是再索要1001A就知道了1001这个数据就是丢了就重传了1001
1001-2000重传之后顺利到达B索要的就是7001
上述的重传过程并没有额外的冗余操作哪个数据丢了就重传哪个没丢的数据就不需要重传整个过程都是比较快速的
如果通信双方传输数据的量比较小也不频繁就仍然是普通的确认应答和超时重传。
如果通信双方传输数据量更大也比较频繁就会进入到滑动窗口模式按照快速重传的方式处理。
通过滑动窗口的方式传输数据效率是会提升的
窗口越大传输效率就越大一份时间等待的ack更多了总的等待时间更少了
当然滑动窗口也不是设置越大越好
如果传输的速度太快就可能会使接收方处理不过来了此时接收方也会出现丢包发送方还得重传。
2.2.5 流量控制
站在接收方的角度反向制约发送方的传输效率
考虑接收方的处理能力
发送方发送的速率不应该超过接收方的处理能力 可以根据缓冲区剩余空间大小来判断消费者处理速度
把剩余缓冲区返回给发送方发送方根据改缓冲区大小发送数据 窗口探测包并不携带具体的业务数据只是为了触发ack为了查询当前接收方这边的接收缓冲区剩余空间。
2.2.6 拥塞控制
不仅仅是接收方还有整个通信的路径 关键问题接收方的处理能力很方便进行量化
但是中间节点结构更复杂更难以直接的进行量化因此可以通过“实验”的方式来找到一个合适的值
让A先按照比较低的速度小的窗口来发送数据
如果数据传输的过程非常顺利没有丢包再尝试使用更大的窗口更高的速度进行发送一点一点变化
随着窗口大小不停的增大达到一定的程度可能中间节点就会出现问题了此时这个节点就可能出现丢包
发送方发现丢包了就把窗口大小调整小此时如果还是继续丢包就继续缩小如果不丢包了就继续尝试变大
在这个过程中发送发不断调整窗口大小逐渐达到“动态平衡” 最终时机发送的窗口大小是取流量控制和拥塞控制中的窗口的较小值
2.2.7 延时应答
A把数据传给BB就立即返回ack给A正常
也有时候A传输给B此时B等一会再返回给ack给A延时应答
本质上也是为了提升传输效率
延时返回ack,给接收方更多的时间来读取接收缓冲区的数据
此时接收方读了这个数据之后缓冲区剩余空间变大了返回的窗口大小也就更大了 2.2.8 捎带应答
在延时应答的基础上进一步的提升效率
网络通信中往往是这种“一问一答”这样的通信模型 ack也是内核立即返回的response则是应用程序代码来返回的这两者的时机是不同的
由于tcp引入了延时应答上面的ack不一定是立即返回可能要等一会
在等一会的过程中B就刚好把response给计算好了计算好了之后就会把response返回与此同时顺便就把刚才要返回的ack也带上了两个数据就合并成了一个数据此时就可以得到更高效的效果
2.2.9 面向字节流
这里有一个最重要的问题粘包问题不是tcp独有的而是面向字节流的机制都有类似的情况
此处“包”应用层数据包如果同时有多个应用层数据包被传输过去此时就容易出现粘包问题 目前接收缓冲区中这三个应用层数据包的数据就是以字节的形式紧紧挨在一起的
接收方的应用程序读取数据的时候可以一次读一个字节也可以读两个字节也可以读N个字节……
但是最终的目标是为了得到完整的应用层数据包B应用程序就不知道缓冲区里的数据从哪里到哪里是一个完整的应用数据包了
相比之下像UDP这样的面向数据报的通信方式就没有上述问题
UDP的接收缓冲区中相当于是一个一个的DatagramPacket对象应用程序读的时候就明确知道哪里到哪里是一个完整的数据。 如何解决粘包问题
核心思想通过定义好应用层协议明确应用层数据包之间的边界
1.引入分隔符
例如可以使用\n作为分隔符
aaa\n
bbb\n
ccc\n 2.引入长度
3aaa
4bbbb
3ccc 自定义应用层协议的格式
xml,json,protobuffer,本身都是明确了包的边界的
2.2.10 异常情况的处理
如果在tcp的使用中出现了意外会如何处理
1.进程崩溃
本质上是进程没了异常终止了。文件描述符表也就释放了相当于调用socket.close(),此时就会触发FIN对方收到之后自然也就返回FIN和ACK这边再进行ACK即正常的四次挥手断开连接的流程
TCP的连接可以独立于进程存在进程没了TCP连接不一定没
2.主机关机正常关机
进行关机的时候就是会触发强制终止进程的操作相当于1此时就会触发FIN对方收到之后就会返回FIN和ACK此时不仅仅是进程没了整个系统也可能关闭了如果在系统关闭之前对端返回的ACK和FIN到了此时系统还是可以返回ACK进行正常的四次挥手。但如果系统已经关闭了ACK和FIN迟到了无法进行后续ACK的响应站在对端的角度对端以为是自己的FIN丢包了重传FIN重传几次都没有响应自然就会放弃连接把持有的对端的信息就删了。
3.主机掉电非正常
此时就是一瞬间的事情来不及杀进程也来不及发送FIN主机就直接停机了站在对端的角度对端不一定知道这个事情
如果对端是在发送数据接收方掉电发送的数据就一直会等待ACK 触发超时重传触发TCP连接重置功能发起“复位报文段”如果复位报文段发过去之后也没有效果此时就会释放连接了 RST复位报文段
如果对端是在接收数据发送方掉电对端还在等待数据到达…..等了半天没消息此时其实是无法区分是对端没发消息还是对方挂了
TCP中提供了心跳包机制形象的比喻即接收方也会周期性的给发送方发送一个特殊的不携带业务数据的数据包并且期望对方返回一个应答如果对方没有应答并且重复了多次之后仍然没有就视为对方挂了此时就可以单方面释放连接了。
4.网线断开
和主机掉电非常类似
当前A给B发送数据一旦网线断开
A就相当于会触发超时重传 - 连接重置 -单方面释放连接
B就会触发心跳包 - 发现对端没响应 - 单方面释放连接
3.对比
TCP和UDP之间的对比
TCP优势在于可靠传输更适用绝大部分场景
UDP优势在于高效率更适用于“可靠性不敏感性能敏感”场景
局域网内部同一个机房的主机之间通信
如果要传输比较大的数据包TCP更优先UDP有64kb的限制
如果要进行“广播传输”优先考虑UDPUDP天然支持广播TCP不支持应用程序额外写代码实现
有一种特殊的场景需要把数据发给局域网的所有机器这个情况就是广播