- 博客(23)
- 收藏
- 关注
原创 nginx反向代理
反向代理:一般是指服务器被代理。正向代理:自己的客户端被代理,例如,vpn。1、http服务器有:1)、iis2)、apache3)、tomcat 动态接口,实现业务从数据库抓取资源,动态资源,给java开发的4)、lighttpd5)、nginx网关:网络层数据出入口网关服务器:应用层数据的出入口,代理服务器,数据先转发到代理服务器,再转发到其他服务器。nginx为什么引用广泛:1)、开源用c写的,优势代码容易读。2)、非常完善的文档。3)、持续的更新。4)、在开源.
2022-01-23 19:52:25
2081
原创 TCP断链四次挥手
1、流程状态图:正常流程黑色部分。fin位置1的tcp包,可以独立发送,也可以和其他数据包一起发送。若需要重传的包中fin置为1,则连同fin包也要一起重传。例如:发送方序列号: 接受方收到的包序列号: 10、11、12、13、14(fin) 10、11、13、14(fin) 这种情况,接受方回ack 确认序列号为12,发送方需要重发12、13、14(fin)包 接受方tcb收到最后的ack才会释放...
2022-01-23 19:05:36
1781
原创 用户态协议栈之Epoll的实现
0、思考问题:如何判断send数据,对方有没有接受成功? send返回正数是没有用的。 send函数做的事情是,将应用需要发送的数据拷贝到协议栈中,用户空间拷贝到内核空间,何时发送的数据包是由协议栈自己决定的。 1、TCP的粘包和分包应用层多次send,第一次send,32字节 第二次send,64字节,协议栈发送粘包96字节解决方案:方案1、在应用层协议里,协议头里加长度的域方案2、每个包加分隔符方案3、发送定长的包,比较低级协议栈里tcp包先发的先到 序号+延迟确认 ..
2022-01-23 18:42:04
1486
原创 用户态协议栈之TCP滑动窗口
1、tcp协议头URG:置为1时,使用紧急 Urgent Pointer指针指向的内容直接给应用层使用2、三次握手三次握手如何实现的:状态机。多个客户端同时请求:每一个客户端都有一个状态机。如何标识每一个客户端:五元组(source ip、source port、dest ip、dest port、protocol)。五元组从哪里获取:对方发送的ip头与tcp头。accept()函数:申请client fd,并将该client fd和accept队列中的一个tcb块绑
2022-01-23 17:42:56
1165
原创 用户态协议栈-TCPIP
用户态协议栈:把协议栈当应用来写网络协议的解析,放到应用层本来协议栈是在系统层,用户态是调用到应用层来写的。系统调用listenaccept为什么会有用户态协议栈1、减少CPU上下切换网卡作用:光电信号(模拟信号)转换为数字信号,AD转换,在物理层和数据链路层之前内核态协议栈处理:网卡把数据放到sk_buff,协议栈对网卡数据进行解析,放到recvbuff中两次拷贝:网卡copy到协议栈 协议栈copy到应用程序将网卡内存映射到内存中间,dma方式,内存.
2022-01-16 20:05:14
1137
原创 hook原理
dlsym()//系统的dlopen()//第三方库#define _GNU_SOURCE#include <dlfcn.h>#include <stdio.h>#include <fcntl.h>#include <sys/select.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/ioctl.h>#include .
2022-01-11 20:25:57
345
原创 协程api
用途:1、文件操作2、mysql操作3、网络io4、redis操作源语:yield resume switch协程api封装几个协程在一个线程里:yield io没有准备就绪,该协程就让给调度器:协程一直不让出会怎么处理?协程是解决io等待挂起,如果没有io操作,用协程意义不大sSS加入sleep队列,时间冲突怎办:key(时间)-value(协程),key重复了 插入失败 key(时间)++(几纳秒) 再++协程多核问题1、采用多.
2022-01-11 20:18:09
238
原创 内存池相关算法
1、伙伴算法,不适合以byte为单位的内存管理,适合以页(4k为1页)为单位的内存管理,即物理内存的分配与回收4k-8byte2k+1K+512+256+128+64+32+16+8申请时,分裂小块回收时,相同大小(2^n字节)的块必须相邻才可以合并成(2^(n+1)字节)大小的块。2、slab策略:将4k空间划分为:若干个8byte,若干个16byte,若干个32byte,。。。3、没有小块回收,要回收一整块都回收。缺少一个回收条件...
2022-01-11 20:13:36
232
原创 网络编程之read和write/send函数
1、数据准备阶段read 函数 :看read buffer里是否有数据,有数据则准备好了,没有数据则没有准备好。 有无数据write/send 函数:看write buffer里面是否数据满了,如果满了,则没有准备好。满的还是非满的2、epoll reactor 使用的是非阻塞io3、阻塞io和非阻塞io都是属于同步io,因为都是用户调用。异步调用是回调,内核调用4、read 和 write 通道都关闭 则会返回 EPOLLHUP5、close(fd),系统只是将fd的引用数量
2022-01-11 20:11:38
601
原创 进程间的信号
1、当网卡收到消息时,触发sigio信号sigio函数,网卡接受到数据之后,通知系统内核,由内核发送给FD对应的应用程序,应用程序处理信号1、进程间的信号集合如何保存?31种信号,每个进程中有一个空间存储,用于存储这31种信号,sigaction-->action[64]2、signal函数如何保存到进程?当来了信号,内核调用signal函数时,将该信号内容(包括信号的处理函数)覆盖到sigaction-->action[sig-1]3、这个信号如何发送来了信号,内.
2022-01-11 19:58:46
92
原创 json数据解析、xml数据解析
可读性:xml > json > protobuf序列化速度xml < json <protobuf序列化大小xml > json > protobufhttp api 接口 json本地配置 xmlrpc protobuf
2021-11-03 22:18:45
152
原创 openssl 对称加密和非对称加密
1、openssl提供一系列开发组件,提供出来的api1)随机数srand();libC里的库;Linux内核提供的专门模块生成随机数:/dev/random 文件里的随机数,随机数频率不高采用;/dev/urandom 文件里的随机数,随机数频率高采用;2)base643)bio,抽象所有的io,file,sockfd,mm,相当于重定向fd4)非对称加密rsa5)对称加密desopenssl实现https客户端如何实现,服务端如何实现...
2021-11-03 20:26:48
316
原创 网络通信标准化ProtoBuf
1、通信协议设计消息帧固定包头+包体结构tcp 保证数据到达,不能保证业务是否处理。2、序列化变长消息体 使用 protobufbase128编码 每一个字节 数据位为7bit 最高一位表示后面是否还有有效字节(0表示没有,1表示有)高位字节放后面,低位字节放前面...
2021-10-31 17:44:26
143
原创 服务端事件
服务端事件组成网络io事件定时事件信号事件reator 使用非阻塞iolibevent和libev都是c语言实现的异步事件库;通过注册异步事件,库检测事件触发,从而库根据 发生事件的先后顺序,调用相应回调函数进行处理; 事件包括:网络io事件,定时事件,信号事件; 事件循环:等待并分发事件;用于管理事件; libevent 和 libev 主要封装了异步事件库与操作系统的交互;让用户不用关注平台的差异,只需着 手事件的具体处理; libevent 和 libev.
2021-10-30 19:40:36
98
原创 try、catch、finally、throw的机制实现
1、使用操作系统提供的API来实现。setjmp、longjmp 这两个函数本身线程安全的goto 在一个函数栈内跳转,短跳。longjmp 可以跨越函数的跳转、函数之间的跳转。//try catch -->setjmp longjmp#include <stdio.h>#include <setjmp.h>jmp_buf env;int count = 0;typedef truct _Exception{ jmp_buf ...
2021-10-29 22:37:20
163
原创 无锁CAS
1、什么是CAS⽐较并交换(compare and swap, CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作,从⽽避免多线程同时改写某⼀数据时由于执⾏顺序不确定性以及中断的不可预知性产⽣的数据 不⼀致问题。 该操作通过将内存中的值与指定数据进⾏⽐较,当数值⼀样时将内存中的数据替换为新的值。2、操作原子i++; 并不是原子性的3、几种锁...
2021-10-29 20:14:37
70
原创 条件等待pthread_cond_wait
pthread_cond_wait()函数結合互斥锁使用pthread_mutex_lock(&mutex)pthread_cond_wait(&cond,&mutex)pthread_cond_wait(scond,&mutex)函数:1、判断cond是否满足,满足就第四步,不满足第二步;2、解除互斥锁;4以上1、2两步是原子操作;3、线程切换为阻塞态,等待条件唤醒该线程;4、如果等待的条件cond满足,解除阻塞,重新获取锁(如果已获取到锁就不用执行获取锁)
2021-10-23 22:54:26
373
原创 各种类型的锁与原子操作
1、什么情况下,需要锁一行代码翻译若干条指令,加锁将多条指令不被拆分。2、lock、trylock、spinlocklock trylock spinlock 线程会休眠 线程不会休眠 线程不会休眠 线程A锁住后,线程B再去申请锁,会引起线程B的挂起,会引起线程的切换 不让线程B切换,线程B有可能被切换 线程B不会被切换,时间片到了也不会引起切换 适用于时间长(大于线程切换时间)粒度大 适用于时间短(小于线程切换时间)粒度小 3、
2021-10-22 23:08:03
276
原创 单时间轮例子
⼼跳检测: 客户端每 5 秒钟发送⼼跳包;服务端若 10 秒内没收到⼼跳数据,则清除连接; 实际在开发过程中,若收到除了⼼跳包的其他数据,⼼跳检测也算通过,在这⾥为了简化流程,只 判断⼼跳包; 作为对⽐:我们假设使⽤ map<int, conn*> 来存储所有连接数;每秒检测 map 结构,那么每秒需 要遍历所有的连接,如果这个map结构包含⼏万条连接,那么我们做了很多⽆效检测;考虑极端 情况,刚添加进来的连接,下⼀秒就需要去检测,实际上只需要10秒后检测就⾏了;那么我们
2021-10-20 21:03:16
121
原创 epoll
1、epoll如何用的int epfd= epoll_create(1);//创建红黑树根节点struct epoll_event ev,events[1024]={0};ev.event = EPOLLIN;ev.data.fd = sockfd;epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&ev);//将绑定的scoketfd添加到前面创建的epoll红黑树中while(1){ int nread = epoll_wait...
2021-10-03 21:09:58
61
原创 信号是如何工作的
1、进程间的信号集合如何保存?31种信号,每个进程中有一个空间存储,用于存储这31种信号,sigaction-->action[64]2、signal函数如何保存到进程?当来了信号,内核调用signal函数时,将该信号内容(包括信号的处理函数)覆盖到sigaction-->action[sig-1]3、这个信号如何发送来了信号,内核回调signal,signal根据sigaction-->action[64]数组下标,找到对应信号的处理函数(即回调函数)...
2021-10-02 11:38:35
82
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人