当前位置: 首页 > news >正文

上国外网站哪个dns快优秀vi设计案例分析ppt

上国外网站哪个dns快,优秀vi设计案例分析ppt,凡科如何开通网站建设,wordpress网站实现微信登录1.UDP 首先我们学习UDP和TCP协议 要从这三个问题入手 1.报头和有效载荷如何分离、有效载荷如何交付给上一层的协议#xff1f;2.认识报头3.学习该协议周边的问题 UDP报头 UDP我们先从示意图来讲解#xff0c;认识报头。 UDP协议首部有16位源端口号#xff0c;16位目的端…1.UDP 首先我们学习UDP和TCP协议 要从这三个问题入手 1.报头和有效载荷如何分离、有效载荷如何交付给上一层的协议2.认识报头3.学习该协议周边的问题 UDP报头  UDP我们先从示意图来讲解认识报头。 UDP协议首部有16位源端口号16位目的端口号16位UDP长度16位UDP检验和。 16位的端口号通过前面网络编程篇章我们知道网络通信必须要有源端口和目的端口号2的16次方也就是 65536 所以端口号范围就是0到65535这里不过多解释了。 16位UDP长度:UDP一次性最大能发送报文长度。16位 那么换算一下就是64KB。也就是说我们最大一次能发送数据就是64KB对于现在的网络来说64KB肯定不够用了。那超出的部分怎么办 如果超过了64KB那么就需要在应用层 手动的分包多次发送并在接收端手动拼装。 通过16位UDP长度我们就可以将报文和数据分离报头的长度是固定的也就是8字节那么报文长度减去8字节 不就是数据大小了吗  16位UDP检验和虽然UDP不保证可靠性但是对方收到报文也要进行检验如果收到的数据不全对方拿着也没有用还不如直接丢弃。 总结通过认识报头我们知道了UDP报文的报头分别是什么意思以及它们的作用。也解决了报头和数据如何分离的问题。  通过示意图还是不够直观的为什么这么说毕竟图片和代码是两个概念很难联系在一起。为了大家能够理解的更深。下面先问大家一个问题 问题UDP没有发送缓冲区但是有接受缓冲区既然有接受缓冲区那么就意味缓冲区里有着大量的UDP报文既然是大量那么OS要不要对这些报文进行管理 明显是要管理的那么如何管理 先描述再组织 所以针对UDP报文管理就转变成了特定的数据结构的增删改查 虽然我们没有见过UDP在Linux操作系统内核是如何实现的但是通过刚才讲解我们也可写一个伪代码。 struct udp_header {uinnt32_t src_port;uinnt32_t dst_port;uinnt32_t length;uinnt32_t check_code; { 既然是自定义类型结构的变量那么我们就可以在堆上开辟空间在缓冲区利用链表进行增删改查 struct sk_buffer {char* start;char* end;char* pos;int type;......struct sk_buffer* next; } UDP特点 UDP类似寄信我们在现实过程中寄信在寄信过程中不需要通知对方我给你寄信了至于对方什么时候收到 我们不知道。人家回不回你的信也是一个问题看人信内容是一次性发给对方的。总不可能你给人家寄信还分上下文吧也就是说我们数据是一次发给对方主机的面向数据报  无连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接; 不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层返回任何错误信息; 面向数据报: 不能够灵活的控制读写数据的次数和数量; 基于UDP的应用层协议 NFS: 网络文件系统 TFTP: 简单文件传输协议 DHCP: 动态主机配置协议 BOOTP: 启动协议(用于无盘设备启动) DNS: 域名解析协议 2. TCP  TCP是非常重要的协议没有之一! 我们学习TCP入手还是从刚才讲解UDP的那样一样。但是众所周知TCP是有接受缓冲区和发送缓冲区而UDP是没有的这就意味着TCP有很多细节。 2.1 理解TCP缓冲区  我们平时用的write read send recv 函数 本质是拷贝函数为什么这么说我们在应用层调用这些系统接口其实是应用层的缓冲区中数据通过这4个函数拷贝到TCP的缓冲区。也就是说 我们平时在应用层定义的那个缓冲区不是TCP的缓冲区。这也是为什么这些函数叫做系统调用接口这正好对应了 数据层层向下交付应用层的数据交付给传输层反之向上也是一样。说到这里你就会有种熟悉感这不就是我们之前讲的文件系统一样的吗 以前是数据 通过系统调用接口 拷贝到OS缓冲区中OS在将数据写入到文件中。文件也是有文件缓冲区的 TCP全称为 传输控制协议(Transmission Control Protocol). 传输 我们知道TCP是个协议我们也知道控制如何理解 控制 就是对传输的控制。比如什么时候发 发多少? 出错了怎么办  TCP是有接受\发送缓冲区的 发多少是由对方主机的缓冲区大小决定的什么时候发由OS自主决定。 出错了TCP也有解决的办法。下面我们先从报文入手认识报文。 2.2 TCP协议段格式 学习报头 我们先解决数据分离 和 向上数据交付。 通过16位的端口号我们就知道如何交付给那一个进程。16位源端口和目的端口号不多多说前面UDP也讲过。 16位端口号的作用就是数据向上交付。 如何分离 可是报头里没有报文的长度啊但是有个4位首部长度。 这个4位首部长度是什么 4位首部长度也就是4个比特位那么四位首部长度取值范围也就是0 到15 可是TCP报头就有20个字节。 这个15 不是明显不够 4位首部长度是带单位的就比如你的工资是2K还是W? 而我们的首部长度的单位是4字节。所以首部长度真实大小是0到60字节  所以选项 最大的取值范围为40字节 选项可以没有  所以数据和报头分离的采取的是固定长度自描述字段。报头大小固定20个字节那么首部长度-减去固定长度 就得到数据的偏移量。这样我们就找到数据的起始位置。                                       16位窗口大小 先说作用填写的是自己接受缓冲区的大小。 TCP要保证自己的可靠性接受缓冲区的里面的内容 如果已经被打满了上层不拿走数据那么此时对方主机再发来数据就要被覆盖。数据丢失如何谈可靠性所以就要有窗口大小。 注意双方基于TCP协议通信的时候互发消息都是完整的报文。且一定是携带的完整的TCP报头                                                                                                                                                       所以双方在进行通信的时候通过16位的窗口大小告诉了对方自己的接受缓冲区的大小是多大这样对面就知道该发多少数据过来了。                                                                                                      32位序号                                                                                                                                         TCP有自己的发送缓冲区而这个发送缓冲区我们可以看做是一个非常大的数组。从应用层拷贝到缓冲区的数据天然就有了序号了数组的下标就是数据的序号。 那序号存在意义 有没有想过我们发送大量报文。前面发送的可能比后面发送的数据后到  如果数据乱序本身就是一种不可靠。 所以序号存在的意义就是要让数据按序拷贝到对方的应用层。 围绕TCP的可靠性 TCP为了可靠性有了一些保证可靠的机制比如应答机制。 32位确认序号  对方主机收到数据会确认序号 会在对方序号1 比如对方发送的数据是1000 那么我们作为接受方会发送一个确认讯号 也就是1001 对方收到应答机制ACK 就意味着 我们收到1001之前的所有数据。                                                                                                      这里就有一个问题了 有了序号 为什么要确认序号 我们确认直接复用序号不就可以了吗 如果我们对序号确认就发一个ACK 那当然没有问题但是 如果我们是数据应答明显复用序号就不行了。 不要忘记了  TCP双方是对等你给我发消息我也要给你发消息。对方给我们发消息 我们刚好也要给对方发消息 而且要告诉对方我们收到他的消息这种方式叫做捎带应答 最直观的就是提高了效率。 6个标记位 为什么要有6个标记位 TCP报文可是有不同的类型而6个标记对应的不同类型报文比如TCP有建立连接的 断开连接的正常的数据通信。而这些场景注定了要有一些符号来标识报文的不同。 URG: 紧急指针是否有效 ACK: 确认号是否有效 PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走 RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段 SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段 FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段 对于ACK 不用多说 前面讲过 确认应答。 SYN/FIN 这个两个也不用多说我们前面讲套接字的时候调用connect 就是SYN建立连接调用close 关闭文件描述符就是FIN。 接受缓冲区的是有16位窗口大小的。也就是说缓冲区的最大值是固定的如果对方一直不读取而我们要发数据但是对方接受缓冲区满了 这时候就要用到PSH TCP 虽然保证可靠性但是TCP是允许建立连接失败的。 双方基于TCP协议通信的时候建立连接是要3次握手如果是A主动对B发起连接SYN 那么 B此时回一个SYNACK这时A就知道了 对方B已经收到我们的请求连接而这时A再发一个ACK 而A就已经认为自己已经和B建立好连接了 所以A就开始发数据了但是有没有一种可能B并没有收到ACK。对于B来说我们3次握手还没有完成过了几毫秒这时B收到对方的数据就会将RST置为1发送完整的报文给A。而A收到了RST就知道了 连接还没有建立。所以重新发起连接请求。 URG 这个标记位我们用的并不多。它作用你可以认为是皇权特许插位。 TCP为了保证数据的按序。但是有些数据比较急就需要对方优先处理。而此时配合16位紧急指针 就知道要处理紧急数据的位置。 紧急数据大小只有一个字节。毕竟TCP要保证可靠性不能乱了主次。 16位紧急指针就是紧急数据的偏移量  2.3 TCP可靠机制 确认应答机制 前面已经提到 可以看前面关于序号的内容。 超时重传机制 主机A发送数据给B之后, 可能因为网络拥堵等原因, 数据无法到达主机B;如果主机A在一个特定时间间隔内没有收到B发来的确认应答, 就会进行重发; 这个就是超时重传机制但是上面的情况是对于B来说数据丢失还有可能是B收到数据了对于A来说ACK丢包了 关于超时重传机制存在对于应答丢失这种情况那么对于对方主机B就会收到大量重复的报文重复大量的报文本身也是一种不可靠的行为。但是超时重传机制又不能不存在。没有超时重传机制TCP的可靠性就无法保证有没有去重的办法 前面讲的序号就是去重的报文的因为在对方的接受缓冲区中之前发来的数据是一直存在的上层没有拿走数据根据序号就我们知道对方重新发来报文进行对比序号一致那么就是重复报文。 那关于超时重传超时多少重传 最理想的情况下, 找到一个最小的时间, 保证 确认应答一定能在这个时间内返回.但是这个时间的长短, 随着网络环境的不同, 是有差异的. 如果超时时间设的太长, 会影响整体的重传效率; 如果超时时间设的太短, 有可能会频繁发送重复的包; 所以超时重传机制重传是动态的。随着次数的增多后面再发送时间会增加如果超时重传时间太长那么对方网络的出了问题这时就关闭我们已经和对方建立好的连接。 连接管理机制 基于TCP协议通信 双方在进行连接时会进行三次握手四次挥手。面试题 那什么又是三次握手四次挥手 三次握手  基于上面这张图我们一一讲解首先我们先看到客户端应用层和服务端应用层 fd write 和read 等等这些函数是不是很熟悉 这就是我们前面套接字。 那么客户端和服务器如果是基于TCP 协议通信此时主动的一方会发起建立连接的请求。大部分都是客户端发起建立连接的请求 这里我们默认都是客户端发起请求。 客户端发起请求会发送一个SYN(这就是一次了)  服务器收到SYN 就会回一个SYN ACK (这就是两次了)  然后 客户端收到 SYN ACK   再发送一个ACK给服务端。这就是第三次了。 TCP为了保证可靠性 一来一回都会发送ACK。这就是3次握手  SYN_SENT 这个状态码叫做 同步发送 同理 SYN_RCVD 叫做 同步收到。 ESTABUSHED 说明本地连接已经建立好了。 这里要强调的有两个函数 connect 和 accept 。当我们客户端调用connect 时也就是请求连接。会被阻塞因为双方建立连接是由双方的操作系统自主决定的也就是说当客户端收到SYN ACK  此时 ESTABUSHED  被设置。如果 建立连接的期间 ESTABUSHED  没有被设置那么connect 一直都是阻塞状态直到收到SYN ACK   同样的 accept 也是一样 如果 本地连接没有建立好。那么上层调用accept 就会被阻塞下层都没有连接拿上来能够用的当然会被阻塞。 四次挥手  当我们建立好连接 就是数据 发送了 你给我发送一个数据我给你一个应答。 如果双方都没有要发的数据了那么此时双方就会断开连接。  断开连接 和 建立连接不一样 毕竟 建立连接 是一方主动一方被动。 断开连接 是要双方协商之后才会断开就如同生活中小明追小美一样一方被动一方主动。当他们结婚以后再离婚可不是说谁 我要离婚就离婚了而是 要经过小明和小美一致同意之后才会离婚。  那么客户端如果没有数据要发了调用 close 此时客户端就会发送一个FIN 给 服务端这就是一次服务端收到之后 再发送ACK给 客户端这是第二次 如果服务端没有要发的数据了那么服务端就会给客户端发送FIN这是第三次客户端收到服务端的FIN 会发送ACK给服务端 这是第四次。 这就是传说中的4次握手。 状态码后面讲 我们先说为什么要三次握手四次挥手。  首先为什么要握手三次我先说原因 验证全双工最小奇数次可以将连接管理的成本嫁接到客户端。   TCP 是平等的你给我发我也要给你发所以当客户端请求服务端建立连接发送完整报头将SYN置为1 对方收到之后 回一个ACK这就证明了 客户端给服务器发送消息没有问题前面也说过你来我往你给我发没有问题但是我给你发有没有问题也是需要验证的。所以客户端再发送一个ACK给服务端 如果服务端收到这就证明了 服务端给客户端发消息也没有问题。 有人说一次可不可以 我们设想一下 如果是一次SYN 那么客户端 就每发一次服务器收到就要建立连接。一台机器就可以给服务器建立大量的连接。连接再内核中也是一种数据结构开辟这种结构体是要耗费内存的连接的管理也有成本的。一次握手就是SYN洪水。服务器压力会很大。 那两次 如果是两次也是优先给服务端建立连接动作当服务器发送ACK 本地连接就建立好了如果客户端不回消息服务端会将这个连接维持一段时间只是几台机器还好说关键是服务器一对多那么如果有大量连接异常服务器维持成本就会很大。所以对于这种情况来说最好是客户端做出让步毕竟客户端只有自己一个连接。 三次就是最小寄数次 将连接的管理成本嫁接到了客户端。有人说5次 7次 可不可以 这就有点画蛇添足了。一次就能做好的事情为什么要返工再做一次或者是多次? 四次 其实3次握手也叫四次握手 因为 按照常理 客户端发SYN 服务端收到 发ACK 然后服务端也要和客户端建立连接发送SYN 客户端收到之后回一个ACK 这其实就是4次。 只不是 服务端那次被捎带应答了也就是 SYN 和 ACK 被压缩成一次了。故而叫做三次握手。 那为什么断开连接是4次 不能三次吗   这是因为 发送数据 双方都有可能发所以断开连接必须两次。一来一回就是4次。三次只有极端情况才有可能客户端想要断开刚好服务器也没有要发的。而这种几率很小毕竟服务器是被动的那么就可以将FIN 和 ACK 压缩成一次。 理解TCP连接时的状态变化 双方建立连接时是双方OS自主决定的也就是说和accept没有任何关系。 listen第二参数是连接管理的最大长度就是一个队列。如果服务器listen第二个参数设置太小 我们假设为9。 那么连接的最大长度就是10 假设我们已经连接了10个客户端那么第11个客户端和服务器进行连接时如果上层accept 没有拿走连接 还是10 个。那么 在服务端来说连接并没有建立好此时会将第11个客户端的请求建立的连接状态还是为 SYN/ RCVD 而客户端则认为自己是建立好了连接 将自己的状态码设置为ESTABLISHED。 SYN/ RCVD要变为 ESTABLISHED 一定是条件满足了条件不满足状态不会发送变化。 TCP保证可靠性原来的全连接队列已经满了。那这个连接会放在那里会放在半连接队列里。 对于服务端来说处于 SYN/ RCVD的状态的连接不会维护太长的时间。  半连接不重要直接跳过。 这里关于listen的参数就有两个问题了 一是为什么不能没有 二是为什么不能太长。 先说为什么要有就好比我们周末去比较火的饭店里吃饭如果去时间比较晚了你会发现在前面还有人排队。如果一个饭店没有排队机制也就是饭店门口没有放座椅话那么这些客人就会走对于饭店来说营业额就会大大降低。那么对于互联网来说也是一样当双11或者双12时。流量访问巨大那么对于服务器压力来说是比较大的如果没有这个机制人家客户连接不上你的服务器还怎么买东西如果我们有了这个管理连接的数据结构那么我们就可以最大化满足客户连接请求。当服务器的压力缓解了立马就能调用accept。 既然有了为什么不能太长这个就非常简单了连接被打满一定是上层出了问题了。比如处理上层的计算任务而这个任务又太大了导致服务器的压力剧增。注意这是一种数据结构也是要耗费内存开辟空间的如果我们设置长度太多服务器本来就忙不过来了还要消耗一部分资源来维护这个连接队列那么就得不偿失了。 基于刚才的情景这就是传说中的连接建立不一致的问题。         这里我们以服务器主动断开的背景来讲。 当服务器主动断开连接时会将自己的状态设置 FIN_WAIT1 此时作为客户端收到了客户端FIN报文那么会将自己的状态设置为CLOSE_WAIT状态 收到之后给予应答ACK。服务端如果收到了ACK会将自己的状态设置为FIN_WAIT2  当客户端也要断开连接时也会发送FIN当对方收到了我们发送的FIN 此时就会将状态设置为TIME_WAIT 当我们收到了服务端发来的ACK此时4次挥手才算完成。也就是正常的断开连接。 理解TIME_WAIT状态 首先只有主动断开连接的一方才会有TIME_WAIT从字面意思来看就是等待一段时间也就是说连接并没有彻底的断开IP 和 Port 正在被使用。 我先说理由 1. 让通信双方历史数据得以消散。 2. 断开连接时双方4次挥手具有较好的容错性。 为什么需要TIME_WAIT状态 确保数据完整性确保所有重复的TCP段在网络中消失避免新连接被旧的重复数据干扰。防止端口耗尽如果立即释放端口可能会与其他服务冲突因为TCP连接是基于四元组源IP、源端口、目的IP、目的端口来识别的。虽然这种概率很小实现可靠传输确保TCP连接的终止是可靠的不会因为网络问题导致连接错误地被认为已经关闭。 那等多久 2MSL等待TIME_WAIT状态会持续一个称为“最大报文段生存时间”Maximum Segment LifetimeMSL的两倍时间。MSL是任何TCP段在网络中生存的最大时间。这个等待时间确保了即使在网络延迟或TCP段被复制的情况下所有的重复TCP段都能在这段时间内消失。资源占用在TIME_WAIT状态下系统会为每个处于此状态的连接保留资源如端口号直到2MSL时间结束。这可能会导致端口耗尽特别是在高并发的服务器上。快速回收在某些操作系统中可以通过设置SO_REUSEADDR套接字选项来允许应用程序快速重用处于TIME_WAIT状态的端口。可以让服务器立即重启前面说过IP和Port正在被使用而端口号只能被一个进程绑定如果不设置我们会绑定失败的。 注意最大报文段生存时间 和 最大传送时长是两个不同概念 报文在网络存活的时间就是MSL而最大传送时长是 A端 到B 端 报文传送时间最大传送时长的时间也就几毫秒而最大报文段生存时间 这个没有定数以Linux 为例 一般是60S 。也就是说这个是秒级的。当然这个也可改 流量控制 接收端处理数据的速度是有限的 . 如果发送端发的太快 , 导致接收端的缓冲区被打满 , 这个时候如果发送端继续发送 , 就会造成丢包, 继而引起丢包重传等等一系列连锁反应 . 因此 TCP 支持根据接收端的处理能力 , 来决定发送端的发送速度 . 这个机制就叫做 流量控制 (Flow Control) ; 那我们怎么知道第一次发送数据时不会打满对面的接受缓冲区? 也就是合理的发送数据 不要忘记了 TCP在建立连接进行3次握手时双方就已经告诉了自己各自16位窗口大小。所以在主动建立连接的一方第三次时其实就可以发送数据了加捎带应答。 那如果双方在后序的发送数据往来时一方的缓冲区被打满了这时另一方基于流量控制的机制那么就不会再发送数据了为了提高效率那如何知道对面的缓冲区已经被上层读取了 作为发送数据的一方会定期发送一个窗口探测的报头询问对方。 而接受的一方也是一样缓存区的数据被上层读走了会立马向对方发送一个窗口更新的报头。 滑动窗口 背景知识 前面讲过TCP为了可靠性发出的报文如果没有收到对应的ACK那么这个报文还是会存在到自己的发送缓冲区。  其二TCP发送报文并不是我们想象中的发一个报文收一个ACK这样效率太过低下而是可以串行的发送大量的报文。也就意味着需要串行的收到大量的ACK这个就好比 微信发送消息一样你可以在对面没有回你消息前一次性可以发送多条消息。 那么大家肯定就会有疑问了那已经发出未收到ACK的报文是存放在发送缓冲区的那个位置 首先TCP将发送缓冲区分成了3个区域第一个区域为已发送已确认第二区域为以发送未确认第三个区域为待发送。 而这个第二个区域就是传送中的滑动窗口。而已发送未确认的报文是在滑动窗口这个区域里面正是因为有了滑动窗口我们才可以发送大量的报文给对方主机。 那如何划分这些区域前面讲过TCP缓冲区就是一个数组我们利用数组的下标充当指针一个开始一个结束滑动窗口本质就是指针的右移这个就是双指针算法。区域不就划分好了吗 收到第一个ACK后, 滑动窗口向后移动, 继续发送第五个段的数据; 依次类推;操作系统内核为了维护这个滑动窗口, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答; 只有确认应答过的数据, 才能从缓冲区删掉; 窗口越大, 则网络的吞吐率就越高; 既然是串行发送大量报文那如果中间的报文丢了怎么办就比如下面这种情况 情况1数据包已经抵达而ACK被丢了。  首先我们要明白确认序号的意义如果中间的丢了这种情况下, 部分ACK丢了并不要紧, 因为可以通过后续的ACK进行确认; 有了确认序号如果我们收到了2000以后确认序号那么1001 到2000 我们也是收到的。 情况2如果是数据直接就丢了 如上图所示1001——2000的数据丢了我们串行发送大量报文对于2000以后的报文对应的ACK序号还是1001如果我们收到的ACK重复了3次会立马补发1001——2000的报文。而这个机制叫做快重传 这里提出了快重传想必大家会有疑问有了快重传为什么还要有超时重传 首先快重传存在的意义是提高效率而快重传这个机制 触发是需要条件的也就是上面说的3次重复的ACK。想一想如果到了后期数据没有这么多了就一两条数据发送能触发快重传吗如果没有了超时重传对于这种情况来说后面的数据可能就收到不到了。 那这个滑动窗口 右移 如何移动 首先窗口的移动只有右移没有左移。窗口大小是动态的变化的也就是说窗口大小不仅取决于对方接受窗口的能力还要看自己的拥塞窗口这个后面讲暂时认为是对方的接受窗口。 前面说滑动窗口算法实现是基于双指针算法如果左指针移动右指针不动那么这个滑动窗口必然是缩小的如果左右指针都移动那么滑动窗口范围要么变大要么变小左移动宽度大于右的那么就是缩小反之变大 如果一直都是左移动右不变那么滑动窗口就变为0了。如果为0意味对方上层一直没有读取数据而且缓冲区被打满。 那如何现实滑动窗口 既然是双指针算法那我们肯定要定义两个指针start 和 end 。 那如何确定这个两个指针的起始位置 我们可以根据TCP的确认序号来确认 int start 确认序号end 确认序号 对方窗口大小暂时认为。 所以到这里你明白了流量控制的实现是基于滑动窗口的。  滑动窗口会不会越界 当然不会越界 TCP采取了类似环状的算法也就是取模运算。 延迟应答  如果接收数据的主机立刻返回ACK应答这时候返回的窗口可能比较小为什么这么说因为虽然对方主机收到了我们发送的数据但是对方主机上层也就是应用层不一定马上就把数据拿上去了。所以缓冲区数据还是有那么就意味着对方主机不能进行窗口更新。 一定要记得 , 窗口越大 , 网络吞吐量就越大 , 传输效率就越高 . 我们的目标是在保证网络不拥塞的情况下尽量提高传输效率; 所以延迟应答的作用就是提高传输的效率本质就是在赌上层能够立即讲数据读走。 那么所有的包都可以延迟应答么 ? 肯定也不是 ; 数量限制: 每隔N个包就应答一次; 时间限制: 超过最大延迟时间就应答一次;   具体的数量和超时时间 , 依操作系统不同也有差异 ; 一般 N 取 2, 超时时间取 200ms 拥塞控制 虽然TCP很可靠但是所有策略都是在两台机器上起作用也就是说如果是网络出现了问题某些机制的触发还有可能造成资源的浪费网络出现了问题超时重传是没有意义的而且还会加重网络拥塞。 如果是在通信时出现了大量的丢包情况那么一定是网络出现了问题面对网络出现了问题TCP当然也替我们考虑到了网络的问题。这时TCP的拥塞控制就会触发。 TCP引入 慢启动 机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据;  此处引入一个概念程为拥塞窗口 发送开始的时候, 定义拥塞窗口大小为1; 每次收到一个ACK应答, 拥塞窗口加1; 每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小做比较, 取较小的值作为实际发送的窗口; 所以真正的滑动窗口的大小是取滑动窗口的有效数据拥塞窗口最小值。  像上面这样的拥塞窗口增长速度, 是指数级别的. 慢启动 只是指初使时慢, 但是增长速度非常快. 为了不增长的那么快, 因此不能使拥塞窗口单纯的加倍. 此处引入一个叫做慢启动的阈值 当拥塞窗口超过这个阈值的时候, 不再按照指数方式增长, 而是按照线性方式增长 如上图所示当TCP开始启动的时候, 慢启动阈值等于窗口最大值;初始值是16 当这个值为24时出现了网络拥塞此时用算法乘法减小对半减24变成12 同时拥塞窗口置回1;。 下次在慢开始时如果这个值到了12了那么后面就是线性方式增长。  3. 面向字节流  那什么是字节流 一直都说TCP是面向字节流的你可以把字节当成水一样。 其实我们上层发送的数据不管是几个或者单个到了下层也就是TCP。转化成二进制几个报文都变成了二进制数据那么也就意味着没有报文概念了全部揉在一起放在TCP的缓冲区中通过滑动窗口一次发送大量的数据过去那么对方收到之后就如同你家水龙头打开一样水流就出来了。至于这个水流是由河水 还是 净化后的自来水TCP各自的接受缓冲区不关心真正关心数据来源以及如何区分这些水那是上层来决定的。 所以我们上层为什么要自己定制协议方便拿到数据之后分析解析数据。 为什么TCP是面向字节流的 这是因为TCP既有发送缓冲区又有接受缓冲区也就意味着读写可以不一一匹配。 由于缓冲区的存在我们调用read 或者 write 假设我们读取100字节那么你可以一次性读100个字节也可以100次读一个字节。对于write也是一样但是UDP就不行。 4.粘包问题 由于TCP是面向字节流上层的数据都揉在一起了加上滑动窗口的存在必定会有报文的数据一部分没有在滑动窗口内那么发送过去对方可能收到的就不是一个完整的报文。这个就是粘包问题。 如何解决 确定好报文之间的边界  对于这个问题前面博客已经讲过了。这里总结一下吧 定长报文特殊字符自描述字段定长报文自描述字段特殊字符。  注意而这个东西也是属于我们自定义协议的一个部分不要和序列化和反序列化搞混了。 5. TCP异常情况  进程被终止那么TCP 建立的连接也是随进程一样释放了因为文件的生命周期是随进程的。 所以机器重启这种情况也是和进程终止一样的。 那如果是网线掉了或者机器掉电了? 对于这种情况来说接收端认为自己的建立的连接还存在。但是如果有写入操作那么接受端就会发现建立的连接不存在了这就是传说中的连接建立不一致的问题那么接收端就会把标志位RST设置. 即使没有写入操作, TCP 自己也内置了一个保活定时器 , 会定期询问对方是否还在 . 如果对方不在 , 也会把连接释放 . 6.文件描述符与socket的关系 文件描述符其实就是个指针数组的指针而这个数组里面的指针指向是一片内存区域的比如文件缓冲区TCP的缓冲区那么在代码中就是结构体套结构体文件系统就是stuct *file 那么网络就是 struct *sock ,那么通过指针指向不同的结构体那么就能执行不一样的代码如果是本地指针指向的是 *file 那么对于就是本地的增删改查的方法如果指向的是*sock那么对应的就是网络中增删改查。 而这个两个结构体都内嵌相对应方法的结构体。 所以这就是C语言的多态。 这里只是简单的说了一说感谢兴趣的读者可以去看内核的源码。 当然 应用层到数据链路层 每一层都有不同处理报文的方法所以这里处理方式也是上面一样指针移动这里指针而不是上面的指针而是内嵌的结构体里面处理增删改查的方法指针所以在TCP缓冲区中每一层数据其实不是向上交付而是通过指针的移动让人感觉就是向上交付。 总结 为什么 TCP 这么复杂 ? 因为要保证可靠性 , 同时又尽可能的提高性能 . 可靠性 : 校验和 序列号(按序到达 确认应答 超时重发 连接管理 流量控制 拥塞控制 提高性能 : 滑动窗口 快速重传 延迟应答 捎带应答 其他 : 定时器 ( 超时重传定时器 , 保活定时器, TIME_WAIT 定时器等 )
http://www.tj-hxxt.cn/news/229677.html

相关文章:

  • 网站改版设计注意事项wordpress过去当前分类id
  • 电子商务网站建设考试试卷广州新一期lpr
  • 易联网站建设电子商务平台经营者通过交易规则
  • 网站建设ahxkjwordpress网站后台
  • 大学做兼职英语作文网站网站前台设计方案
  • 如何制作手机网站网站建设 容易吗
  • 巩义服务专业网站建设北京seo的排名优化
  • html5手机网站制作教程wordpress会员组
  • 金泉网网站建设wordpress封装app
  • 建设网站的功能及目的是什么意思谷歌商店下载官网
  • 青州建设局网站sem是什么职业岗位
  • 网站服务器费用工程建设标准化
  • 台州企业网站seo2 网站建设的一般步骤包含哪些
  • 做网站可以卖别的牌子的产品吗无锡市住房与城乡建设局网站
  • 网站内容及实现的方式有路由器做网站
  • next.js做纯静态网站asp.net网站思路
  • 开发一个网站需要几个人软件设计属于什么专业
  • 网站风格的设计外贸网站做SEO
  • 软件开发外包网长沙防疫优化
  • 上海制作网站的公司有哪些建设网站能自学吗
  • 网站改版301网站后台添加图片显示不了
  • 珠海专业机械网站建设买房网站怎么做
  • 句容市建设工程管理处网站建网页还是网站好
  • windous 系统 做网站网站开发合同里的坑
  • 有名的wordpress网站电商网站的特点
  • 陶艺品网站模板wordpress 阅读
  • 网站联系我们模板wordpress响应式cms
  • 什么网站程序适合做seo加强官网建设
  • wordpress网站运行时间代码施工企业市场调查目的与主题主要有()。
  • 网站h1标签怎么做如何网上快速接网站开发订单