【完结12章】基于C++从0到1手写Linux高性能网络编程框架

woaiwodejia333 · · 870 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
【完结12章】基于C++从0到1手写Linux高性能网络编程框架 分享一套课程——基于C++从0到1手写Linux高性能网络编程框架,已完结12章,附源码+电子书。大家下载学习。 Socket 网络编程框架 Socket(套接字)是一个网络编程概念,描述了一个通信端点(Endpoint),用于建立网络连接(Connection)并传输数据。 Linux Kernel 提供了一套面向 Socket 的网络编程框架,并通过提供一组标准的 System call APIs,使得开发者可以在 Userspace 中便捷的开发各种 Network Applications,例如:基于 HTTP 协议的 Web 服务器、基于 SMTP 协议的邮件服务器、基于 FTP 协议的文件服务器等等。 Linux Socket 网络编程框架主要由 3 大模块组成: 1、BSD Socket APIs 2、Socket Abstraction Layer 3、VFS Layer TCP通信的实现过程 TCP通信的实现过程主要包括三个阶段:建立连接、数据传输和连接释放。 建立连接 在TCP通信开始之前,发送方和接收方需要先建立连接,以便在传输数据时能够互相识别。 a. 三次握手 发送方首先向接收方发送一个SYN(同步)包,用于请求建立连接。接收方收到SYN包后,回复一个ACK(确认)包,表示接收到请求。同时,接收方也向发送方发送一个SYN-ACK包,表示接收方准备好了建立连接。发送方收到SYN-ACK包后,回复一个ACK包,表示连接建立成功。 这个过程被称为“三次握手”,是为了确保双方都能正确地识别对方并建立连接。 b. 建立连接后的数据传输 连接建立后,发送方可以向接收方发送数据,数据会按照TCP协议进行分组、封装、校验和传输。接收方会根据TCP协议对数据进行解封、校验和重组,确保数据的正确性。 TIME_WAIT状态存在原因有两点: 其一是可靠的中止tcp连接; 其二是保证让延迟的tcp报文有足够的时间被识别; 客户端在关闭连接阶段需要处理收到重复的结束报文,然后回复最后的ACK给服务端,否则客户端在收到服务端的FIN就直接回复ACK,这样后续服务端重传的FIN包都会被回复RESET报文,这时服务端认为是错误报文,这就是第一点存在的原因; 那么第二点是为了不让同一个tcp端口被多次打开或者是断开以后马上被一个新的连接接管,这样存在数据安全和处理异常等问题,让tcp最大时间坚持2MSL也是为了确保重发和延时的tcp包在这段时间内被丢弃(使用端口复用采用socket选项SO_REUSEADDR); tcp超时重传和拥塞控制 tcp服务必须能够重传超时时间内未收到的tcp报文段。 为此,tcp模块为每一个tcp报文都维护一个重传定时器,linux两个重传相关的内核参数: /proc/sys/net/ipv4/tcp_retries1和/proc/sys/net/ipv4/tcp_retries2 前者表示tcp最少执行重传次数,默认为3; 后者表示tcp最多执行重传次数,默认为15; tcp服务有重传必然就会导致拥塞,那么接下来介绍网络底层如何进行拥塞控制? 拥塞控制包括四个部分:慢启动,拥塞避免,快速重传和快速恢复; 在此之前还需要介绍窗口概念:RNWD(接收窗口,指前面tcp报文中的对端发送的win窗口),CWND(拥塞窗口,是系统定义的一个状态变量大小),SWND(发送窗口,是RNWD和CWND之间的较小值); 在tcp模块刚开始发送数据阶段并不知道网络的实际情况,需要试探性地增加CWND,这一过程称为慢启动,CWND初始值设置为2-4个MSS;然后发送端每次收到接受端的一个确认,就按照公式: CWND += min(N, MSS) 其中N是此次确认中包含的之前未确认的字节数; 如果随着CWND不断累加,不加控制会造成网络拥塞,那么需要进行拥塞避免算法,界定慢启动和拥塞避免过程通过慢启动门限(ssthresh)控制,当CWND超过ssthresh则进入拥塞避免阶段; 拥塞避免阶段控制CWND是每个RTT时间都计算(如果RTT时间内收到多少确认包),公式: CWND += SMSS*SMSS/CWND 这样就保障了CWND缓慢增长,直到传输超时或者tcp重传定时器溢出,就需要重新调整ssthresh,再次进入慢启动阶段,那么ssthresh计算公式: ssthresh = max(FlightSize/2, 2MSS) 其中FlightSize已经发送但是还未收到确认的字节数; 另外一种情况:在接受端接收到重复的确认报文段的时候,tcp模块如何处理? 如果发送端收到3个重复的确认报文,认为拥塞发生,启动快速重传和快速恢复,先计算ssthresh; 然后通过CWND = ssthresh + 3 * SMSS计算出CWND,再次每收到1个重复确认时,设置CWND += SMSS,最后当收到新数据的确认时,直接设置CWND = ssthresh,这样快速重传和快速恢复完成,又再次进入拥塞避免阶段。 网络协议栈的集成 网络协议栈是实现网络通信的核心部分,包括IP协议、TCP/UDP协议、路由、ARP等。为了实现高性能网络应用,可以考虑以下几点: 1)、使用硬件加速技术:一些网络设备支持硬件加速功能,例如卸载协议栈的一部分功能到网络设备中,利用硬件加速处理数据包。 2)、优化协议栈参数:通过调整协议栈的各种参数来优化性能,包括接收和发送缓冲区的大小、超时时间、滑动窗口等。 3)、选择合适的协议栈:根据应用的需求选择合适的协议栈,例如使用高性能的协议栈(如DPDK)。 5、性能调优和测试 在构建网络驱动程序后,需要进行性能调优和测试,以确保驱动程序能够达到预期的性能要求。可以通过以下几点来进行性能调优和测试: 1)、使用性能分析工具:例如perf、ftrace等工具来分析性能瓶颈和优化性能。 2)、进行基准测试:通过搭建测试环境,模拟实际网络负载,并对驱动程序进行基准测试,评估其性能。 3)、进行系统优化:根据测试结果进行系统优化,包括内核参数的调整、硬件资源的优化、中断处理的优化等。 构建Linux内核网络驱动程序是实现高性能网络应用的关键步骤。在构建过程中,需要进行硬件设备的初始化和配置、中断处理、网络收发处理、网络协议栈的集成等工作,并进行性能调优和测试,以确保驱动程序能够达到预期的性能要求。通过以上步骤的综合优化,可以构建高性能的Linux内核网络驱动程序,提升网络应用的性能和吞吐量。 ![QQ截图20231221145336.png](http://static.itsharecircle.com/231221/a4f09d22bf19dfa400c6107a1b5d9a2a.png)
870 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传