网络编程
CL_XYZ
这个作者很懒,什么都没留下…
展开
-
关于muduo库中EventLoop的runInLoop功能
EventLoop可以在他的IO线程中执行某个用户任务回调,即EventLoop::runInLoop(const Functor& cb)其中Functor是boost::function<void()>。 如果用户在当前IO线程中调用这个函数,回调会同步进行;如果用户在其他线程调用runInLoop,cb会被加入队列,IO线程会被唤醒来调用这个Funct...原创 2019-03-14 13:33:07 · 1740 阅读 · 0 评论 -
使用CAS操作实现的无锁栈
CAS(compare and set),是原子数支持的一种操作,假如我们有一个原子数类,那么他其中的CAS函数大致可以理解为这样bool compare_and_set(T&a,T&b){ if(*this==a) { *this=b; return true; } else { a=...原创 2019-04-07 17:58:16 · 604 阅读 · 0 评论 -
C++11线程池
线程池其实就是把任务队列和工作线程绑到一起,提供一个向任务队列中添加任务的接口,下面的代码为了表达更加清楚没有分成头文件和源文件,仅仅是提供思路。同步机制利用的互斥锁+条件变量,也可以使用C++11提供的原子数封装的自旋锁+条件变量。两种组合的区别在于,自旋锁比较适合当任务比较简单的时候使用,可以减少陷入内核的次数,但当任务比较复杂,线程需要较长时间等待的时候,自旋锁会把大量时间浪费在忙等待上...原创 2019-04-05 17:36:53 · 184 阅读 · 0 评论 -
connect accept listen 与三次握手的关系
首先明确三次握手发生在什么时候。经过我的验证,在客户端执行connect的时候,便是向已经listen的服务器发出三次握手,等connect返回的时候,三次握手已经完成,和accept没有任何关系。验证过程如下。客户端程序只执行到connect,服务器端程序只执行到listen,然后用tcpdump对本地进行抓包。这里要注意tcpdump想抓本地还回的包需要监听 lo 也就是tcpdump...原创 2019-03-27 11:08:21 · 2269 阅读 · 2 评论 -
tinyhttpd源码剖析
这是一个简单的服务器程序,只有五百多行。每次来一个请求就开一个线程去处理它,可以解析POST,GET而且可以执行CGI程序。服务器程序想要把自己收到的参数传给某些别的程序去执行,并且把这些程序产生的输出拿走,发给某个目标对象。CGI所处的位置就在“服务器把收到的参数传给别的程序”这个环节。它规定了一个标准的借口,我们只需要调用setenv()把收到的东西设置成条件变量,然后再通过execl执行...原创 2019-04-04 20:58:24 · 740 阅读 · 0 评论 -
为什么IO复用要搭配非阻塞IO和应用层buffer
为什么IO多路复用要搭配非阻塞IOselect、poll_wait、epoll_wait返回可读≠read去读的时候能读到。如果不用非阻塞,程序会永远卡在read上。以上情况可能出现在多进程同时监听一个socket,只有一个进程可以accept,别的都会block。假如socket的读缓冲区已经有足够多的数据,需要read多次才能读完,如果是非阻塞可以在循环里读取,不用担心阻塞在read上,...原创 2019-03-13 15:30:51 · 620 阅读 · 1 评论 -
常见的并发网络服务程序设计方案总结
0.非并发while(1){ clientsock=accept(); while(1) { str=recv.clientsock() //block if(str) send.clientsock(str); else { close(clientsock); break; } }}一次只服务一个客户,阻塞在recv上,浪费时间。1....原创 2019-03-13 14:42:54 · 155 阅读 · 0 评论 -
多线程环境下的高效异步日志系统
多线程双缓冲异步日志https://github.com/chenlujiu/High-Performence-AsyncLogStream.gitIntroduction仿照了MUDUO的日志设计,在原有的基础上做了简化,仅供学习。EnvoirmentOS: Ubuntu 14.04Complier: g++ 4.8Technical points异步实现这个日志模块用于多...原创 2019-03-13 12:05:47 · 1423 阅读 · 2 评论 -
CLOSE关闭连接的各种情况
由于涉及面太广,只作简单整理,有兴趣的可参考《UNIX Networking Programming》volum 1, Section 5.7, 5.12, 5.14, 5.15, 6.6 以及7.5 SO_LINGER选项。以一个简单的echo服务器为例,客户端从标准输入读入字符,发送给服务器,服务器收到后再原样返回,客户端收到后打印到标准输出。那么,关于套接字的关闭有以下几种情形:1,客...转载 2019-03-12 20:34:35 · 1805 阅读 · 0 评论 -
TCP产生复位报文段RST的三种情况
在某些特殊情况下,TCP连接的一端会向另一端发送携带RTS标志的报文段,即复位报文段,以通知对方关闭连接或重新建立连接。访问不存在的端口当客户端程序访问一个不存在的端口时,目标主机将给他发送一个复位报文段。异常终止连接TCP提供了异常终止连接的方法,即给对方发送一个复位报文段。一旦发送了复位报文段,发送端所有排队等待发送的数据都将被丢弃。应用程序可以使用socket选项SO_LINGER...原创 2019-03-12 20:06:15 · 1291 阅读 · 0 评论 -
为什么存在TIME_WAIT 状态
客户端连接在收到服务器的结束报文段之后,不会直接进入CLOSED状态,而是转移到TIME_WAIT状态。在这个状态,客户端连接要等待一段长为2MSL,即两倍的报文段最大生存时间,才能完全关闭。其原因主要有两点:可靠地终止TCP连接。保证让迟来的TCP报文段有足够的时间被识别并丢弃。第一个原因很好理解,客户端在收到来自服务端的FIN之后,要返回一个ACK,如果这个ACK丢失,服务端会因超...原创 2019-03-12 19:28:53 · 1138 阅读 · 0 评论 -
简述muduo库中的Thread类
本文根据自己的看法对muduo库中的thread类进行了一定程度的简写。为什么要对线程进行封装?这是我在当初阅读这部分源码的时候萦绕在心头的一个问题。现在我想我可以对这个问题稍作解答。封装线程的目的是为其主线程构建一个方便操作副线程的接口。我们在进行多线程编程的时候,势必要对副线程进行管理,在理想情况下,程序里的线程都是用同一个class创建的,这样容易在线程的启动和销毁阶段做一些统一...原创 2019-03-15 17:33:25 · 1305 阅读 · 1 评论 -
muduo库发送数据简述
TCP连接发送数据和接收数据的处理方式略有不同,并没有让IO复用函数全权负责,这样做减少了程序从poll函数返回的次数,提高了服务器的效率。具体做法是,当消息产生可以像某个socket写入的时候,我们可以调用runInLoop,让IO线程在执行doPendlingFunctor的时候替我们做发送的操作。具体来看TcpConnection模块的代码。void TcpConnectio...原创 2019-03-15 11:03:15 · 1023 阅读 · 1 评论 -
epoll详解
IO复用函数统共有三个,select,poll,epoll,但是在大并发条件下,我们一般都会使用epoll,select和poll有下边两个缺点。每次在调用之前都要把所有需要监控的socket都传给内核 无论是在内核还是在用户空间select和poll都是采用轮询的方式检查所有socket而epoll正是在这两点上做出了改进,得到了比select和poll更高的效率。epoll的原理...原创 2019-04-03 20:24:20 · 500 阅读 · 0 评论