- 博客(48)
- 收藏
- 关注
原创 五种IO模型
IO为输入/输出,从内存的视角来理解,用于在内存与外设之间进行交互,网络通信的本质也属于IO范畴,以服务器端进行read为例子,当read的时候,本质是在做拷贝,在这个过程中,需要等待数据就绪,就绪后才进行拷贝;高效的IO,就是在单位时间内,IO中等待的比重越低,IO效率越高,设计高效的IO,就要减少单位时间内,IO中等待时间的比重。在内核将数据准备好之前,系统调用会一直等待,所有的套接字,默认都是阻塞方式。获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETKW)
2026-04-16 15:20:30
153
原创 NAT代理、内网打洞和内网穿透
当某一主机访问目标服务器时,目标服务器收到的客户端的IP,其实不是内网IP,收到的其实是运营商的出入口路由器WAN口的IP,报文从主机发送到服务器的过程中,每经过一个路由器,都会通过NAT转换表进行转换,如果将双方的IP地址进行交换,那么就可以直接发送到对应的路由器,这种通过中间的公共服务器做中转,可以直接访问对应路由器的技术,称为内网打洞技术。如果两个报文源地址的端口号一样,经过NAT路由器后,都会映射到同一IP地址和端口号,此时IP地址+端口号就不唯一了,也就没办法做映射了。
2026-04-15 07:30:46
367
原创 数据链路层
一开始交换机中的条目为空,后面会进行自学习,当主机A要给主机E发消息时,交换机发现自己收到的数据帧是从左边进来的,因此,左侧记录下MacA,同时会将MacE传到右侧,主机E收到数据后,若进行回应,目的地址为MacA,源地址为MacE,此时交换机确定MacE在交换机的右侧,经过几轮这样的学习,交换机就会将多个主机的Mac地址分别存在左右两侧的条目,若当有新的数据帧到来时,发现目的地址在同侧,则不转发;任何主机,也可能曾将向别人发起过ARP,那么未来对应的主机也会得到应答,该主机有可能会收到ARP应答。
2026-04-13 16:07:50
376
原创 网络层IP
路由器LAN口连接的主机,都从属于当前这个路由器的子网中,不同的路由器,子网IP其实都是一样的,通常都是192.168.1.1,子网内的主机IP地址不能重复,但是子网之间的IP地址就可以重复了,也就是私有IP地址是可以重复的,由于这个原因,IP地址不足的问题也被大大缓解了。---------------------------------------------------------------- 按位与。目的IP是具有指向性的,主机是根据报文中的目的IP,进行路由选择的。
2026-04-12 11:12:10
422
1
原创 传输层协议UDP和TCP
同样的,一开始A给B发数据时,也会携带自己16位窗口大小的信息,确保B能知道A的窗口大小。在三次握手建立连接的过程中,最后一次发送ACK没有应答,因此这个报文能不能被服务器收到是不确定的,客户端只要把最后一个携带ACK的报文发送出去了,客户端就认为连接已经建立了,若最后一个携带ACK的报文丢失了,服务端此时处于一个半连接的状态,但是,客户端此时可能就要开始发送数据了,服务器此时收到了正常的数据,但由于服务器还没有完全建立起连接,此时,服务器向客户端发送一个携带RST=1的报文,告诉客户端连接建立异常。
2026-04-02 16:23:56
405
原创 应用层协议HTTP
HTTP(HyperText Transfer Protocol,超文本传输协议)是网络中一个至关重要的协议,它定义了客户端(如浏览器)与服务器之间的通信,以交换或传输超文本。HTTP协议是客户端与服务器之间通信的基础。客户端通过HTTP协议向服务器发送请求,服务器收到请求后处理并返回响应。HTTP是一个无连接、无状态的协议,即每次请求都要建立新的连接,且服务器不会保存客服端的状态信息。Http本质和浏览器底层,用的都是TcpSocket,用的都是ip+port的进程间通信机制。
2026-03-27 06:34:12
389
1
原创 序列与反序列化
Jsoncpp是⼀个用于处理JSON数据的C++库。它提供了将JSON数据序列化为字符串以及从字符串 反序列化为C++数据结构的功能。Jsoncpp是开源的,广泛用于各种需要处理JSON数的C++项目中。除了解决序列化的问题,还要定制完整的协议格式,以确保接收方接收的信息是完整的,报文格式如下图所示:报文前面4字节表示简单的报头,代表有效载荷长度,中间的有效载荷为序列化之后的字符串,当接收方读取报文时首先读取有效载荷的长度,并读取对应大小的内容作为有效载荷的内容,以此来解决粘包问题。
2026-03-14 08:40:47
406
原创 Socket编程TCP
之前我们简单介绍了UDP相关函数及使用,这篇文章我们重点来介绍TCP,由于TCP与UDP的通信过程有许多相似的地方,因此本文只介绍TCP相较于UDP不同的地方。
2026-03-10 18:39:57
66
原创 Socket编程UDP
创建socket的函数声明如下:创建成功后,函数返回文件描述符,若创建失败则会返回-1,并设置错误码;函数第一个参数domain,为通信时使用的领域,常用的为AF_UNIX和AF_INET,AF_UNIX为创建本地套接字文件,AF_INET为创建网络通信的套接字;第二个参数type表示是用户数据报式的通信还是面向字节流式的通信;第三个参数protocol为具体的协议。在UDP通信时,domain选择AF_INET,type选择SOCK_STREAM或SOCK_DGRAM,protocol设置为0即可。
2026-03-05 15:16:30
422
原创 计算机网络基础概念
在网络通信的过程中,数据传输到主机并不是最终的目的,因为数据是给人用的,所有数据最终都要传递给对应的进程,源IP地址和目的IP地址保证主机之间的通信。而交给对应的网络进程,是通过端口号来实现的。端口号是传输层协议的内容,是一个2字节16位的整数,端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理。网络通信的本质,其实是进程间的通信。进程的pid是系统概念,端口号属于网络的概念,如果将pid当做端口号来用,那么系统和网络之间就会产生强耦合。
2026-02-11 10:11:18
585
原创 线程的互斥与同步
之前我们在使用多线程时发现,一个进程内部的多个线程中,因为所有的线程共享地址空间,进程资源大部分都会被线程共享,如果多个线程同时访问一个共享资源,例如多个线程同时向显示器打前言。
2026-01-30 16:49:12
383
原创 Linux信号机制详解:从产生到处理
发送信号的方式有很多,主要是围绕用户、硬件、软件各种场景展开的,但是无论以什么方式发送信号,最终都要借助操作系统之手向目标进程写信号。该函数的相关声明如下:该函数可以更改指定进程更改信号处理动作,第一个参数为目标信号,第二个参数为函数指针类型,函数表明了接收到信号要执行的动作,函数指针的形参代表是收到了哪一个信号,才执行的。对信号进行自定义捕捉时,只需要程序的开始位置定义一次即可。函数执行成功时,返回SIG_ERR,一般为-1,代表老的动作,方便后续进行恢复。
2025-12-17 15:29:05
739
原创 常见的进程间通信方式详解
之前我们介绍的进程之间的独立性很强,但是,如果进程之间想要进行协同工作,该怎么安排进程之间的工作呢?这篇文章我们就来简单介绍下进程通信的相关话题。数据传输:一个进程需要将它的数据发送给另一个进程资源共享:多个进程之间共享同样的资源通知事件:一个进程需要向另外一个或一组进程发送消息,通知发生了某种事件(如进程终止时要通知父进程)进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。
2025-12-14 20:40:10
725
原创 C++智能指针
之前我们介绍了C++11的特性,除了之前介绍过的,智能指针也是C++11一个非常重要的新语法,这篇文章我们就来简单介绍下只能指针。
2025-11-25 21:57:14
964
原创 C++11新特性全解析
之前我们介绍了C++的相关语法,但之前的介绍大多是基于C++98标准的,C++11标准在C++98的标准上进行了扩充,这篇文章就简单介绍一下C++11新扩展的语法。
2025-11-21 11:51:27
726
原创 深入解析进程创建、终止与等待
进程创建主要是通过fork()函数完成的,内核主要做以下几个工作:分配新的内存块和内核数据结构给子进程将父进程部分数据结构内容拷贝至子进程添加子进程到系统进程列表当中fork返回,开始调度器调度。
2025-11-19 18:47:39
577
原创 虚拟地址空间:揭秘Linux内存
在学C语言或者C++时,我们学过内存分区的概念,对栈区、堆区等分区有了基本的理解。这篇文章我们会对这部分进行更详细的介绍。
2025-11-08 17:13:21
1027
原创 探索Linux命令行参数与环境变量
环境变量在系统没有启动之前,默认是存在bash内部的,bash是在内存中,因此命令行参数和环境变量表是存在内存中的,是内存级临时的表。之前也介绍过,之前自己编写的程序和命令等,启动起来都是bash进程的子进程,而子进程是可以看见父进程定义的数据的,这子进程能得到环境变量的原因。之前我们介绍过,自己写的编译好的可执行程序不能直接通过程序名运行起来,而是要通过"./[文件名]"的方式才能运行,这个本质上就是告诉操作系统,用户要执行的bin,就在当前路径下。常见的环境变量有很多,这里我们只介绍做常用的PATH。
2025-11-04 09:56:00
767
原创 GDB调试实战:快速掌握程序调试技巧
之前我们介绍了如何使用vim编译器、gcc/g++编译器以及make自动化构建等工具,通过以上工具,我们就可以完成代码的编写及其运行。但是在windows的IDE中,还有调试功能,这篇文章我们就简单介绍下调试的常用选项。
2025-10-30 14:54:55
598
原创 深入解析Linux操作系统进程状态
之前我们简单介绍了操作系统中进程的相关概念,以及如何启动进程。在进程工作周期中,不同阶段的进程所对应的状态也不一样,这篇文章我们就简单介绍下进程的状态。
2025-10-29 16:20:47
563
原创 探索Linux进程:从理论到实践
在Linux中,除了指令和工具,还有非常重要的部分——进程,这篇文章我们就简单介绍一下进程。任何一个计算机系统都包含一个基本的程序集合,称为操作系统(OS)。不同概念的操作系统包括的内容也不一样,如下图所示:这里我们讨论的是狭义上的操作系统。内核的四大功能包括内存管理、文件管理、驱动管理和进程管理,在任何计算机类的设备,都是需要有这四大功能的,只不过不同操作系统会在不同的功能上添加一些外壳程序(如图形化界面),来方便用户使用。
2025-10-26 23:39:03
889
1
原创 Linux自动化构建:make与makefile详解
之前我们学了gcc/g++的使用,以及程序的编译过程,了解如何使用编译器对文件进行编译。但是,实际开发中,一个项目的文件数量是非常多的,我们不可能将所有文件名一个个输入并进行编译,在使用Windows相关IDE时,相关IDE已经帮我们完成了自动化构建的工作,在Linux中,其实也有相关的自动化构建工具,这篇文章我们就来介绍make和makefile。make其实就是一条命令,makefile其实就是一个文件。
2025-10-24 16:10:44
676
原创 红黑树:平衡与高效的完美结合
之前我们讲解过了AVL树的概念以及实现,在AVL数中,为了使查找的效率达到O(log N),通过控制根结点的左右子树高度差的绝对值不大于1,保证整棵树是高度平衡的,从而提高找到效率,当左右子树的高度差大于1时,通过旋转保证左右子树高度差不大于1,。但是,高度平衡也是AVL树的一个劣势,当插入大量随机结点时,AVL树可能旋转次数过多,相应的时间开销也会增加。今天我们将介绍红黑树,它是通过控制黑色结点的数量来保持平衡的。
2025-10-19 02:01:34
1093
原创 Linux下gcc/g++编译指南
之前我们介绍了如何使用vim编辑器来对文本进行编辑,掌握了vim编辑器的用法之后,我们就可以在Linux中高效地编写代码。在编写完代码之后,我们还需要对代码进行编译,本文章就简单介绍如何使用编译器gcc/g++对代码进行编译。gcc是一个C语言编译器,只能用来进行编译C语言,g++是一个C++/C语言编译器。两个编译器的使用基本相同,本文章以gcc的使用为例。
2025-10-16 19:35:16
617
原创 vim高效编辑:从入门到精通
之前我们在windows使用Visual Studio,该软件集成了编写代码、编译、调试和运行的功能,这种将多个功能集于一体的软件称作IDE,但是在 Linux系统中,编写代码、编译代码、调试和构建工具这几个是独立分开的,今天我们介绍一个用来写代码的编辑器vim。
2025-10-14 14:49:23
930
原创 每日一题——长度最小的子数组
题目要求从正整数数组中找出和≥target的最短子数组长度。暴力解法时间复杂度高,使用滑动窗口优化:维护左右指针和窗口和,右指针扩展窗口,左指针收缩窗口以寻找最小长度。时间复杂度O(N)。代码实现中,通过循环更新最小长度,最终返回结果或0(无解)。该方法高效且符合题目要求。
2025-10-10 13:34:56
1044
原创 每日一题——三数之和
本文分析了力扣算法题"三数之和"的两种解法。首先介绍了暴力枚举法,虽简单但时间复杂度高(O(n³))。重点阐述了优化解法:先排序数组,固定一个数后,在剩余区间使用双指针寻找两数之和等于目标值。通过跳过重复元素提高效率,并处理边界条件。最终给出了C++实现代码,时间复杂度优化至O(n²)。
2025-10-07 15:34:06
942
原创 AVL树的概念及实现
AVL树是一种自平衡二叉搜索树,通过旋转操作保持平衡,确保查找时间复杂度稳定在O(log N)。其性质包括:可以是空树、左右子树高度差不超过1。实现时引入平衡因子(右子树高-左子树高)来维护平衡。插入新节点后,需更新平衡因子并检查是否失衡。若失衡,则进行四种旋转操作(左单旋、右单旋、左右双旋、右左双旋)来恢复平衡。旋转过程需注意节点关系调整和平衡因子更新,确保树结构符合AVL树性质。通过这种方式,AVL树始终保持高效查找性能。
2025-10-06 18:25:41
975
原创 set容器和map容器的使用
本文介绍了C++中两种关联式容器set和map的基本概念及使用方法。set容器基于红黑树实现,具有自动排序和去重特性,支持多种构造函数、迭代器遍历、插入删除等操作,但不允许修改元素值。multiset与set类似但不自动去重。map容器则存储键值对,同样基于红黑树实现,支持快速查找、插入和删除操作。文章通过代码示例详细展示了set容器的构造、迭代器使用、元素插入、查找和删除等核心功能,并比较了set与multiset的区别。这些关联式容器提供了高效的数据存储和检索能力,适用于需要快速查找和有序存储的场景。
2025-08-18 22:31:25
918
原创 二叉搜索树介绍及实现
本文介绍了二叉搜索树的基本概念、构建过程、性能分析及C++实现。二叉搜索树是一种左子树节点值均小于根节点,右子树节点值均大于根节点的特殊二叉树。文章详细展示了通过序列构建二叉搜索树的过程,并指出其中序遍历结果是有序的。性能分析表明,最优情况下时间复杂度为O(logN),最差为O(N)。在实现部分,给出了存储结构定义,并详细讲解了查找、插入和删除操作的算法逻辑与代码实现,其中删除操作需根据子节点情况分三种情况处理。通过图示和代码示例,全面展示了二叉搜索树的核心操作原理。
2025-08-17 00:18:30
616
原创 优先级队列(priority_queue)及仿函数
本文介绍了优先级队列的概念、实现及应用。优先级队列是一种按优先级处理数据的特殊队列,默认采用大根堆结构实现。文章通过C++代码示例展示了优先级队列的基本操作,包括push、pop等,并分析了其堆结构的存储特点。在实现部分,详细讲解了如何基于适配器模式使用vector容器作为底层存储,并实现了向上调整和向下调整等核心算法。此外,文章还介绍了仿函数的概念及其在自定义排序规则中的应用,展示了如何通过仿函数实现升序/降序控制。通过Date类的例子,进一步说明了如何自定义比较规则。全文从理论到实践,系统地讲解了优先级
2025-08-13 12:29:13
704
原创 Linux权限
本文介绍了Linux系统中的权限管理机制。主要内容包括:1. Linux权限的基本概念和分类(读、写、执行);2. 用户分类(超级用户和普通用户)及切换方法;3. 角色分类(拥有者、所属组和其他)及其验证规则;4. 文件属性解读和权限的字符与八进制表示方法;5. 文件权限的设置方法(chmod、chown、chgrp);6. umask的作用和计算方法;7. 粘滞位的概念及其应用场景。这些内容系统阐述了Linux系统中如何通过权限机制实现文件资源的安全管控。
2025-07-24 20:57:19
1063
原创 C++入门——引用
在之前的C语言中,我们写过一个交换函数,由于形参值的改变不影响实参的改变,所以我们要传地址进行交换,因此函数的两个参数为一级指针。*x = *y;*y = *x;通过调用该函数,我们可以实现两个变量数据的交换,但是,这里用到了指针,很多初学者对指针的概念和使用不是那么熟练,如果场景再复杂一点,可能会涉及到二级指针或者多级指针,对编写程序的人造成了很大的困扰;同时,对阅读该程序的人也增加了一定的阅读成本。
2025-04-19 06:45:59
702
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅