自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(66)
  • 收藏
  • 关注

原创 多路转接 select

select可以一次性等待多个fd,一旦有其中任意一个就绪就会通知上层,告诉调用方,哪些fd已经可以IO了,

2025-08-11 21:46:55 861 11

原创 五种 IO 模型与阻塞 IO

我们在读数据的时候client向server要数据的时候是要等对方发过自己的接受缓冲区才有数据,IO了不一定有数据,也有可能在网络里跑要等,还有我们调用read等系统调用向内存要数据,其实是假借操作系统之手,创建子进程,继承文件描述符表,继承pcb其他数据,通过文件描述符找到数据在拷贝回来,这也要时间,所以IO的时候,我们可以认为。

2025-08-10 15:31:29 888 19

原创 NAT、代理服务、内网穿透

数据链路层的作用: 两个设备(同一种数据链路节点)之间进行传递数据以太网是一种技术标准;既包含了数据链路层的内容, 也包含了一些物理层的内容. 例如: 规定了网络拓扑结构, 访问控制方式, 传输速率等;以太网帧格式理解 mac 地址理解 arp 协议理解 MTU。

2025-08-09 16:14:14 604 3

原创 数据链路层

ARP 协议建立了主机 IP 地址 和 MAC 地址 的映射关系.在网络通讯时,源主机的应用程序知道目的主机的 IP 地址和端口号,却不知道目的主机的硬件地址,数据包首先是被网卡接收到再去处理上层协议的,如果接收到的数据包的硬件地址与本机不符,则直接丢弃,因此在通讯前必须获得目的主机的硬件地址,arp就是用来将ip地址转化为mac地址。注意到源 MAC 地址、目的 MAC 地址在以太网首部和 ARP 请求中各出现一次,对于链路层为以太网的情况是多余的,但如果链路层是其它类型的网络则有可能是必要的。

2025-08-03 16:51:43 1153 7

原创 网络层概述

应用层是用户去处理的,数据传输过来干嘛用的由我们自己去实现,传输层是TCP,UDP协议,用来保证可靠性,是面向数据包还是面向字节流,就好比空运还是车运,各有各的好处,场景不一样,网络层是IP协议,路由器选择路径用来保证数据从这个主机发给那个主机的,数据链路层是保证在子网内通信用ARP协议替换ip给mac实现报文递交,在我们看来路由器交给路由器其实就是局域网给局域网,只不过一个路由器有两个ip而已。

2025-07-31 15:01:59 1065 8

原创 传输层协议 TCP

TCP 全称为 "传输控制协议(Transmission Control Protocol"). 人如其名, 要对数据的传输进行一个详细的控制。

2025-07-20 21:01:31 1159 4

原创 传输层协议 UDP

我们注意到, UDP 协议首部中有一个 16 位的最大长度. 也就是说一个 UDP 能传输的数据最大长度是 64K(包含 UDP 首部).然而 64K 在当今的互联网环境下, 是一个非常小的数字.如果我们需要传输的数据超过 64K, 就需要在应用层手动的分包, 多次发送, 并在接收端手动拼装;在 TCP/IP 协议中, 用 "源 IP", "源端口号", "目的 IP", "目的端口号", "协议号" 这样一个五元组来标识一个通信(可以通过 netstat -n 查看)UDP 传输的过程类似于寄信.

2025-07-17 14:58:38 890 3

原创 应用层协议 HTTP

虽然我们说, 应用层协议是我们程序猿自己定的. 但实际上, 已经有大佬们定义了一些现成的, 又非常好用的应用层协议, 供我们直接参考使用. HTTP(超文本传输协议)就是其中之一。在互联网世界中,HTTP(HyperText Transfer Protocol,超文本传输协议)是一个至关重要的协议。它定义了客户端(如浏览器)与服务器之间如何通信,以交换或传输超文本(如 HTML 文档)。HTTP 协议是客户端与服务器之间通信的基础。

2025-07-10 23:45:28 1187 5

原创 如何将服务守护进程化

刚刚我们谈到了进程组的概念, 那么会话又是什么呢?会话其实和进程组息息相关,会话可以看成是一个或多个进程组的集合, 一个会话可以包含多个进程组。每一个会话也有一个会话 ID(SID)通常我们都是使用管道将几个进程编成一个进程组。如上图的进程组 2 和进程组 3 可Shell# &表示将进程组放在后台执行# 用管道和 sleep 组成一个进程组放在后台运行# 查看 ps 命令打出来的列描述信息# 过滤 sleep 相关的进程信息。

2025-07-07 14:42:51 710 24

原创 应用层自定义协议与序列化

我们程序员写的一个个解决我们实际问题, 满足我们日常需求的网络程序, 都是在应用层.

2025-06-30 19:05:10 1062 13

原创 Socket 编程 TCP

和刚才 UDP 类似. 实现一个简单的英译汉的功能。

2025-06-26 21:47:26 1137 12

原创 Socket 编程 UDP

简单的回显服务器和客户端代码,本地回环,要求c,s砸啊哎同一台机器,本地通信,client发送的数据不会被推送到网络,而是在OS内部绕一圈交给对应的服务器,一般用于网络代码的测试。1.bind公网IP --不行 公网IP没有配置在机器里公网IP无法直接bind,云服务器是内部处理过的。如果我们显示的进行绑定,client未来访问的时候,就必须使用server端bind的地址,否则找不到。服务器手动分配为零,允许接受任何报文,自动分配任意IP地址,否则指定IP只能对应的IP+地址才能访问,

2025-06-17 17:41:53 406 5

原创 Linux网络基础概念

首先回答,两台主机在同一个局域网,是否能够直接通信?是的,每台主机在局域网上,要有唯一的标识来保证主机的唯一性:mac 地址。

2025-06-16 17:17:22 1103 2

原创 线程池封装

一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。需要大量的线程来完成任务,且完成任务的时间比较短。比如WEB服务器完成网页请求这样的任务,使用线程池技术是非常合适的。

2025-06-07 22:21:24 828 24

原创 网络基础概念

截止到目前,我们还没接触过任何协议,但是如何朴素的理解协议,我们已经可以试试了。OS 源代码一般都是用 C/C++语言写的。下面,仔细看看下面的图:

2025-06-05 20:41:10 1024 24

原创 日志与策略模式

IT行业这么火, 涌入的人很多. 俗话说林子大了啥鸟都有. 大佬和菜鸡们两极分化的越来越严重. 为了让菜鸡们不太拖大佬的后腿, 于是大佬们针对一些经典的常见的场景, 给定了一些对应的解决方案, 这个就是 设计模式。

2025-06-01 21:12:12 948 8

原创 POSIX信号量

POSIX信号量和SystemV信号量作用相同,都是用于同步操作,达到无冲突的访问共享资源目的。本质就是一个计数器,是对特定资源的预定机制,本身相比于基本类型,POSIX信号是原子的,POSIX可以用于线程间同步,信号量把对临界资源是否存在,就绪等的条件,以原子性的形式呈现在临界资源前就判断了。

2025-05-30 20:25:56 886 3

原创 Linux线程同步

生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。当队列满时,往队列里存放元素的操作也会被阻塞,直到有元素被从队列中取出(以上的操作都是基于不同的线程来说的,线程在对阻塞队列进程操作时会被阻塞)条件等待是线程间同步的一种手段,如果只有一个线程,条件不满足,一直等下去都不会满足,:因为时序问题,而导致程序异常,我们称之为竞态条件。

2025-05-25 19:32:49 748 33

原创 线程封装与互斥

在多线程编程中其他的线程都执行move,寄存器和mutex内都是0,交换完还是0,全部进了下一个调度队列,直到拥有锁的线程执行完释放锁,把1写回mutex,才能轮到下一个线程申请锁成功,如果没有申请成功,锁被占用了,执行else挂起等待,等拥有锁的释放锁后,才可以执行后面的代码申请锁区访问临界支援,说白了,谁交换走了1,谁就持有锁,谁就有优先访问临界资源的权力。但有时候,很多变量都需要在线程间共享,这样的变量称为共享变量,可以通过数据的共享,完成线程之间的交互。上述代码用多线程模拟抢票,但是为什么抢到负数?

2025-05-23 19:38:13 1277 21

原创 Linux线程控制

所以,我在自己的代码里面调用pthread_create,是在动态库内部帮我们创建动态库描述的控制块,管理块的开头叫TCB,里面包含了描述线程的相关信息,而TCB里包含了void *ret字段,而当前线程运行结束的时候,会把自己的退出状态写到自己的控制块ret里,然后主线程又和新线程共享地址空间,主线程也就能通过起始地址+偏移量找到对应线程的控制块,主线程通过pthread_join拿到对应的退出状态拷贝回来,进程结束LWP自动释放,但是库里的东西没被释放,LWP查不到内存泄漏。怎么理解这个“ID”呢?

2025-05-15 15:46:41 1286 20

原创 线程概念与控制

在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”,一切进程至少都有一个执行线程,线程在进程内部运行,本质是在进程地址空间内运行 在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化,透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流以前我们说的进程其实是只有一个线程的进程,叫轻量级进程PCB,每个进程有独立的页表,独立的虚拟内存,有自己的struct等数据结构。

2025-05-04 17:29:54 690 27

原创 Linux进程信号

访问零号地址,操作系统拿到的是虚拟地址,cr3寄存器可通过页表的地址找到页表,MMU将cr3的页表地址和要访问的0号地址做虚拟的页表转化,但是页表下在零号地址没有对应的映射关系,转化失败,硬件报错,cpu的寄存器无法把100写到0号地址处,发送11号信号,终止进程。上面的所有内容,我们都没有做非常多的解释,主要是先用起来,然后渗透部分概念和共识,下面我们从理论和实操两个层面,来进⾏对信号的详细学习、论证和理解。发送固定的6号(SIGABRT)信号给自己,要求进程必须处理,目的就是终止进程。

2025-04-04 21:13:08 1463 43

原创 进程间通信--匿名管道

管道是Unix中最古老的进程间通信的形式。

2025-03-15 21:14:39 843 32

原创 库制作与原理

库是写好的现有的,成熟的,可以复用的代码。细节:动静态库g++/gcc默认使用动态库,非静态链接只能-static,一旦-static,就必须得存在对应的静态库,只存在静态库,可执行程序对于该库,只能静态链接了。头文件包含了方法的声明,库包含了方法的实现,所以,对库的安装,其实就是将对应的头文件,库文件拷贝到系统的指定文件下,将来编译时只要指定库名称,gcc自动找头文件和库文件。在Linux系统下,默认安装大部分库,默认优先安装动态库,库:应用程序=1:n,vs不仅可以形成可执行程序,也能形成动静态库。

2025-03-07 20:50:13 1258 41

原创 Linux文件系统

机械磁盘是计算机中唯一的一个机械设备磁盘--- 外设,慢,容量大,价格便宜磁盘的存储结构扇区:是磁盘存储数据的基本单位,512字节,块设备如何定位一个扇区呢?柱面(cylinder),磁头(head),扇区(sector),显然可以定位数据了,这就是数据定位(寻址)方式之一,CHS寻址方式。

2025-02-22 18:05:11 1346 36

原创 文件基础IO

进程里面有一个stuct*file能找到文件描述符表, file是一个结构体,里面含有文件的各种属性,fd是指针数组,里面通过下标能访问到各自file,文件被打开时,创建file文件,再把file存入文件描述符表中最小的空的fd里面,fd通过地址文件能找到file能访问文件。进程在调用read等接口时操作系统拿着fd索引来到文件描述符表找到该fd内的file地址,每一个文件都要有自己的文件缓冲区,操作系统预加载,file找到缓冲区,将缓冲区的内容拷贝给read等接口自己的缓冲内,所以读写的本质就是拷贝!

2025-02-06 22:00:06 1054 42

原创 linux 进程补充

在bath进程启动的时候,在它自己内部构建出一张表,在用户输入指令时首先被bath拿到,被拆分成若干个字符串放在argv[0],argv[1],argv[3]...指针数组argv指向他们,bath通过argv【0】下的程序名字找到path下的二进制来运行。其实Linux里面的指令都是二进制文件,然后再链接我们总结写的文件,最后汇到一块一起运行,要运行一个二进制文件,必须先找到它 ./是在文件树下找,但是我把二进制拷贝到home下,系统默认的路径下我们不带./也能跑,这也是其他指令的由来。

2025-02-05 00:10:28 1883 26

原创 linux进程

在系统当中查找一个最合适调度的进程的时间复杂度是⼀个常数,不随着进程增多而导致时间成本增加,我们称之为进程调度O(1)算法!

2025-01-14 22:40:45 1496 44

原创 MSQL操作案例

createdatabase 数据库名:使用create命令创建一个数据库,database关键字后面接自定义数据库名字,默认UTF-8编码(utf8_ general_ ci)

2024-12-05 18:25:45 2770 71

原创 C++11

目录4. 可变参数模板4.1 基本语法及原理4.2包括展4.3 empalce系列接口5. 新的类功能5.1 默认的移动构造和移动赋值5.2.声明给缺省值5.3 defult和delete5.4 final 与 overator6.STL中一些变化7. lambda7.1 lambda表达式语法 7.2 捕捉列表7.3 lambda的应用7.4 lambda的原理8. 包装器8.1 function8.2 bindC++11支持可变参数模板,也就是说支持可变数量参数的函数模板和类模板,可变数目的参数被称

2024-11-10 22:35:44 789 79

原创 C++11

编译器在实现C++的时候为了形成逻辑的闭环,右值的右值引用可以被修改,属性退化。所以,我们在实现接口的时候实现完美转发避免这种问题,也可以完美转发。

2024-11-10 00:17:57 985 58

原创 Linux开发工具

vi/vim的区别简单点来说,它们都是多模式编辑器,不同的是vim是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面。目前处于[插入模式],就只能一直输入文字,如果发现输错了字,想用光标键往回移动,将该字删除,可以先按一下「ESC」键转到[正常模式]再删除文字。控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode。在使用末行模式之前,请记住先按「ESC」键确定您已经处于正常模式,再按「:」冒号即可进入末行模式。

2024-10-19 19:48:58 932 45

原创 C++中set的使用

• set的声明如下,T就是set底层关键字的类型• set默认要求T⽀持⼩于⽐较,如果不⽀持或者想按⾃⼰的需求⾛可以⾃⾏实现仿函数传给第⼆个模版参数• set底层存储数据的内存是从空间配置器申请的,如果需要可以⾃⼰实现内存池,传给第三个参数。• ⼀般情况下,我们都不需要传后两个模版参数。• set底层是⽤红⿊树实现,增删查效率是 O(logN) ,迭代器遍历是⾛的搜索树的中序,所以是有序的。

2024-09-26 17:03:18 1679 70

原创 二叉树进阶

⼩区⽆⼈值守⻋库,⼩区⻋库买了⻋位的业主⻋才能进⼩区,那么物业会把买了⻋位的业主的⻋牌号录⼊后台系统,⻋辆进⼊时扫描⻋牌在不在系统中,在则抬杆,不在则提⽰⾮本⼩区⻋辆,⽆法进⼊。:商场⽆⼈值守⻋库,⼊⼝进场时扫描⻋牌,记录⻋牌和⼊场时间,出⼝离场时,扫描⻋牌,查找⼊场时间,⽤当前时间-⼊场时间计算出停⻋时⻓,计算出停⻋费⽤,缴费后抬杆,⻋辆离场。:统计⼀篇⽂章中单词出现的次数,读取⼀个单词,查找单词是否存在,不存在这个说明第⼀次出现,(单词,1),单词存在,则++单词对应的次数。找N左⼦树的值最⼤结点。

2024-09-23 16:37:26 1407 85

原创 C++中的多态

多态是⼀个继承关系的下的类对象,去调⽤同⼀函数,产⽣了不同的⾏为。⽐如Student继承了Person。Person对象买票全价,Student对象优惠买票。2.1.1 实现多态还有两个必须重要条件:• 必须指针或者引⽤调⽤虚函数• 被调⽤的函数必须是虚函数。说明:要实现多态效果,第⼀必须是基类的指针或引⽤,因为只有基类的指针或引⽤才能既指向派⽣类对象;第⼆派⽣类必须对基类的虚函数重写/覆盖,重写或者覆盖了,派⽣类才能有不同的函数,多态的不同形态效果才能达到。2.1.2 虚函数。

2024-09-17 15:09:23 3113 90

原创 Linux基本指令

touch命令参数可更改文档或目录的日期时间,包括存取时间和更改时间,或者新建一个不存在的文件。:对于目录,该命令列出该目录下的所有子目录与文件。复制: ctrl + insert (有些的 insert 需要配合 fn 来按)Linux系统中,磁盘上的文件和目录被组成一棵目录树,每个节点都是目录或文件。touch一个不存在的文件113,ll展开文件发现新建了一个113文件。:在当前目录下创建一个名为 “dirname”的目录。将当前工作目录改变到指定的目录下。: ls [选项][目录或文件]

2024-09-09 19:54:50 925 54

原创 【数据结构】二叉树

通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。这里我们从倒数的第一个非叶子结点的子树开始调整,一直调整到根结点的树,就可以调整成堆。删除堆是删除堆顶的数据,将堆顶的数据根最后一个数据一换,然后删除数组最后一个数据,再进行向下调整算法。:一个结点含有的子树的根结点称为该结点的子结点;

2024-08-24 18:33:03 1085 59

原创 【数据结构】栈和队列

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有。:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。压栈:栈的插入操作叫做进栈/压栈/入栈,出队列:进行删除操作的一端称为。

2024-08-23 14:45:17 883 66

原创 【数据结构】链表

链表的结构跟火车车厢相似,淡季的时候车次的车厢会相应减少,旺季的时候车次的车厢会额外增加几节,只需将火车里的某节车厢去掉/加上,不影响其他车厢,每节都是相互独立的。链表中每个节点都是独⽴申请的(即需要插⼊数据时才去申请⼀块节点的空间),我们需要通过指针变量来保存下⼀个节点位置才能从当前节点找到下⼀个节点。当我们想要从第⼀个节点⾛到最后⼀个节点时,只需要在前⼀个节点拿上下⼀个节点的地址(下⼀个节点的钥匙)就可以了。链表是线性表的一种,物理结构不一定是线性的,逻辑结构一定是线性的。

2024-08-20 20:12:32 2406 58

原创 数据在内存中的存储

其实超过⼀个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分为⼤端字节序存储和⼩端字节序存储,下⾯是具体的概念:⼤端(存储)模式:是指数据的低位字节内容保存在内存的⾼地址处,⽽数据的⾼位字节内容,保存在内存的低地址处。(低放高)⼩端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,⽽数据的⾼位字节内容,保存在内存的⾼地址处。(高放低)上述概念需要记住,⽅便分辨⼤⼩端。

2024-08-20 00:23:40 1270 51

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除