西安建设网站电话上海网页设计公司哪家最好
西安建设网站电话,上海网页设计公司哪家最好,wordpress网站如何加百度搜索,桂林两江四湖游#x1f3ac; 胖咕噜的稞达鸭#xff1a;个人主页#x1f525; 个人专栏: 《数据结构》《C初阶高阶》 《Linux系统学习》 《算法日记》⛺️技术的杠杆#xff0c;撬动整个世界! UDP协议
UDP 报文结构
定长报头#xff1a;UDP 报头固定为 8 字节#xff0c;由 4 个 16 位… 胖咕噜的稞达鸭个人主页 个人专栏: 《数据结构》《C初阶高阶》《Linux系统学习》《算法日记》⛺️技术的杠杆撬动整个世界!UDP协议UDP 报文结构定长报头UDP 报头固定为 8 字节由 4 个 16 位字段组成16 位源端口号16 位目的端口号16 位 UDP 长度整个报文的长度16 位 UDP 校验和数据部分报头后面跟着应用层交付的数据长度可变。核心要点分离与分用分离UDP 报头是定长的8 字节所以接收方可以轻松地从字节流中分离出报头和数据。分用通过目的端口号操作系统可以将收到的数据报准确地交付给对应的应用程序socket。面向报文UDP 对应用层交付的数据不做拆分或合并直接封装成一个独立的报文进行传输。每个报文都有明确的边界这与 TCP 的字节流模型不同。协议本质是结构体在代码层面UDP 报头可以直接用 C 语言的struct udphdr结构体来表示字段和报文格式一一对应。操作系统内核在处理网络数据时本质上就是在操作这些结构体实现了高效的数据传递。UDP的特点UDP传输的过程就像寄信。无连接知道对端的IP和端口就直接进行传输不需要建立连接不可靠没有确认机制没有重传机制如果因为网络缘故该段将无法发送到对方UDP协议层也不会给应用层返回任何错误信息面向数据报不能够灵活的控制读写数据的次数和数量原样发送不会拆分也不会合并发送100个字节收到的就是100个字节)UDP的缓冲区UDP没有真正意义上的发送缓冲区调用sendto会直接交给内核由内核将数据传送给网络层协议进行后续的传输动作。UDP具有接收缓冲区但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致如果缓冲区满了再次到达的UDP数据就会被丢弃。UDP的socket既能读也可以写。UDP 数据报发送出去后若丢失协议本身不会重传。数据从发送缓冲区发出后会被删除不会保留也不支持二次重传。保留数据并自动重传是 TCP 的机制。对报文的理解Tcp协议确认应答机制tcp协议段格式标准问题1.1 问题报头和有效载荷如何分离的TCP协议标准报头长度是 20 字节报头不是定长的如果报头要添加选项实际长度 标准长度 选项长度一般为 0。TCP 标准报头里有 4 位bit的首部长度字段单位是 4 字节TCP报头至少 20 字节TCP 报头长度范围[20, 60] 字节4 位首部长度字段的取值范围[5, 15]。1.2 如何交付的问题tcp中有16位源端口号16位目的端口号在传输层收到了一个tcp报文sk_buff收到之后提取目的端口号服务器刚好bind过端口号根据端口号可以查询当前的进程就可以把报文交给目的端口了完成交付。可靠性的本质客户端给服务器端发信息具有应答可以保证对历史消息的可靠性如果要保证可靠性tcp处于核心地位的确认应答机制通信中最新的报文永远没有应答最新可靠性无法保证。问题 TCP一般的通信过程发送大量的报文再对每一个做应答。但是如果有一个丢包了怎么办tcp协议段格式中为什么需要有序号确认序号 序号 1就是说指定报文序号之前的所有的信息已经全部收到。下一次发送从确认序号开始。怎么说原因一假如我发送报文100确认应答的时候对端发送过来的是101说明刚刚发送的100对方收到了我发送100200300400最后收到的对端应答为401还是可以说明我发送的100200300400都被对端收到了。指定序号之前都收到了因为允许少量的应答可以丢失。原因二与此同时通信过程还有乱序问题也是属于不可靠的问题最开始发送的报文不一定比刚刚发送的报文 到达对端的时间晚在操作系统内部不是每一个报文经过的路径都是相同的所以就会出现乱序问题。这也是tcp协议有32位序号的好处有序号进行排序可以解决乱序问题。问题 但是为什么有两个序号啊对16位窗口大小的理解为什么需要有16位窗口大小是做什么的假如发送端给接收端发信息想发多少就发多少如果接收端的接收能力太弱那么一大堆数据在到达对方接收端的缓冲区阻塞住造成数据丢包这就是一种浪费资源的低效做法。虽然我们也可以数据重传但是“由多大肚子吃多少饭”更有利于通信就有了16位窗口大小。确认应答的都是报头接收端把自己接收缓冲区的剩余空间的大小写到16位窗口大小中这样发送端就可以看到了就知道接收端的接收能力了根据接收能力发送数据进行流量控制。问题一台主机接收数据的能力由什么决定由接收缓冲区中剩余空间的大小决定。tcp保留6位标志位实际上就是位段比特位超时重传机制丢包重新理解应答报文正向反向问题发送方没有收到应答ACK,意味着什么我们无法100%保证对方是否收到消息无法保证可靠性。只能意味着数据可能丢失对方可能没有收到。就是说要么数据丢要么应答丢。无论是哪一种我们都无法确定。所以我们就需要等待等待应答。还需要约定一个特定的时间间隔再这个特定的时间间隔内收不到应答我们就可以判定报文确实是丢失了。收不到应答 超时 -------丢包了。问题这个时间间隔是多久等待的时间长度是变化的。其跟网络的情况有关系网络差就时间间隔长一点好就短一点。最理想的情况下找到一个最小的时间保证“确认应答”一定可以在这个时间内返回但是这个时间的长短随着网络环境的不同还是有差异的如果超时的时间设置过长就会影响整体的重传效率如果超时的时间设置过短就会频繁发送重复的数据包。TCP为了保证无论在任何网络环境下都可以比较高性能地通信就会动态计算这个最大地超时时间超时以500MS为一个单位进行控制每次判定超时重发的超时时间间隔都是500ms的整数倍问题超过了时间间隔我们重新传输了一次数据到达主机B但是如果数据没有丢包在数据链路中传输的时间超过了这个时间间隔最终再一次数据到达主机B这个时候出现了报文重复问题对于重复的报文该如何处理会直接丢掉此时我们的序号就发挥了作用确认应答按序到达去重。去重这一操作就会把多出来的一份数据自动丢弃。连接管理机制问题理解SYN_SENTESTABLISHED,这些状态跟服务器与客户端连接有什么关系以学校抢选修课为例子分析一下图中的每一个SYN_SENT都是一个状态每一个状态都是一个整数管理在连接中所以连接要有结构体struct Link管理这些状态。所以每一个客户端连接到服务器上都是需要建立连接建立连接需要时间空间的成本一旦同一时间连接的客户端太多了服务器就会挂掉。这也就是为什么我们在学校选课的时候的时候会特别卡而且服务器崩掉的原因。问题用户和内核层面怎么进行三次握手用户层面connect发起三次握手accept接收accept不参与三次握手。内核层面上SYN,SYNACK,ACK。问题:为什么要进行三次握手以最短的方式进行验证全双工本质上是验证我们两个所处的网络是通畅的可以支持全双工以最小成本100%确认双方通信意愿。问题为什么是三次握手四次挥手面对客户端的连接请求服务器都要无脑应答双方挥手的时候需要征求双方同意。三次握手比四次挥手少了一次服务器的应答因为面对客户端的连接请求服务器需要无脑应答在此处少了一个服务器的询问客户端“我需要跟你建立连接”服务器将“好啊” “你需要我帮你做什么”合并为“好啊你需要我帮你做什么”。所以本来应该是四次握手四次挥手。问题四次挥手又是什么断开连接的本质断开连接的本质是建立双方断开连接的共识做法C-S我要发送的数据已经发送完毕了我要跟你断开S-C我给你发送的数据已经发完了我也要断开连接,断开连接双方都要同意本质也即是建立双方通信的共识建立全双工通信。问题图中CLOSE_WAIT是什么分析一下为什么会导致文件描述符fd)泄漏本质上是TCP连接关闭流程和服务器代码逻辑的问题。先看TCP四次挥手的角色当客户端主动关闭连接时会先发送FIN包服务器收到后进入CLOSE_WAIT状态客户端FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED服务器ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED服务器在CLOSE_WAIT状态时还没有主动关闭连接所以对应的文件描述符 fd 仍然被占用不会被系统回收。为什么客户端退出/关闭后服务器还在CLOSE_WAIT这是因为服务器代码里没有正确处理客户端断开的事件客户端主动调用close()发送 FIN服务器内核收到后把连接状态改成CLOSE_WAIT。但服务器的应用程序业务代码没有调用 close(connfd)导致内核不知道应用层已经处理完了不会发送 FIN 包给客户端。连接一直停留在CLOSE_WAIT对应的 fd 也一直被占用。如果这种情况反复出现就会造成 fd 泄漏服务器打开的文件描述符越来越多最终达到系统限制无法接受新连接。核心原因应用层没有“收尾”TCP 连接是全双工的断开需要双方达成共识客户端说“我发完了要断开FIN。”服务器必须回应“我也发完了要断开FIN。”如果服务器应用层不调用 close(connfd)就等于没说这句话连接就卡在CLOSE_WAITfd 也一直占着。怎么避免必须在处理完客户端请求后显式调用close(connfd)让服务器端也完成挥手。或者使用shutdown()优雅关闭再调用close()。代码里要处理异常比如客户端断开、读超时等场景都要保证 fd 被正确关闭。简单总结CLOSE_WAIT是服务器 “收到了客户端的断开请求但自己还没说要断开” 的状态如果应用层不主动close连接和 fd 就永远释放不了这就是 fd 泄漏的根源。主动断开连接的一方要进入一个状态叫做TIME_WAIT,即是四次挥手完成。TCP协议规定主动关闭连接的一方要处于TIME_WAIT状态等待两个MSL的时间之后才能回到CLOSED的状态。使用ctrlc终止了server服务器server是主动关闭连接的一方。MSL在RFC1122中规定给为两分钟但是各个操作系统的时间长度是不一样的在Centos7/Ubuntu默认配置是60s.可以通过cat/proc/sys/net/ipv4/tcp_fin_timeout来查看这个值。