Linux下有三种I/O复用模型,select、poll、epoll
为什么要用I/O复用模型呢?
计算机资源有限,线程号也有限。如果一个线程管理一个I/O请求,在I/O请求很多的时候并不能适应。
用I/O复用模型就可以一个线程管理多个I/O。
在
poll使用基本流程.png
按这个流程写的只能称之为 玩具代码,可能出现一些问题
1.read 可能并没有把connfd所对应的接收缓冲区的数据都读完,那么connfd仍然是活跃的
- 这本身是没有问题的,但是应用层发送过来的数据包,刚好分包了。一个数据包,两次read才能接收完全的话,就可能会发生粘包问题。
我们应该将读到的数据保存在connfd的应用层接收缓冲区。
2. write 如果发送缓冲区满了 write并不能把所有数据都发送
write发送的时候,我们也应用有一个应用层的发送缓冲区。
POLLOUT事件 触发条件,connfd的发送缓冲区不满(可以容纳数据了)
(如果一开始就关注POLLOUT事件可能会出现,忙等待)
(POLL 其实也是LT 电平触发,不支持ET。EPOLL和POLL 的LT 一样)
EMEFILE处理.png最可取的是,最后一种处理方式。
image.png
(先接收过来,再断开避免busy loop)
Linux网络编程 第12讲 tcp11种状态中
如果客户端关闭套接字close
而服务器,调用了一次write,服务器会接收到一个RST segment(TCP传输层)
如果服务器再次调用了write,这个时候就会产生 SIGPIPE信号。(如果没有忽略这个信号的话,这个信号的默认方式就是推出我们的进程)
TIME_WAIT状态 对大并发服务器的影响
应该尽可能在服务器端避免出现TIME_WAIT状态
什么时候会出现TIME_WAIT状态呢?
如果服务器端 主动断开连接(先于client调用close),之后服务器端就会进入TIME_WAIT。这样的话在内核中就会hook住一些单元,并发能力下降。
协议设计上,应该让客户端主动断开连接,这样就把TIME_WAIT状态分散到大量的客户端。
如果客户端不活跃了,一些恶意客户端不断开连接,这样就会占用服务器的连接资源。
服务器端也要有一个机制来踢掉不活跃的的连接 close
man socket
man fcntl
nonblocking socket + I/O复用
image.png
C++ 11 第一个元素首地址可以这么写polldfs.data();
-1表示永远等待
image.png
cmake
sudo apt-get install cmake
需要配置一个 CMakeList.txt
文件
cmake .
当前CMakeList.txt
所在目录
编译出来的可执行文件在bin目录下
set_-x
shell编程的知识
Linux编程知识得学一下
网友评论