网络:4.TCP并发服务器

1.TCP并发服务器问题

  • 服务端需要连接多个客户端时,服务器需要使用accept等待三次握手连接,同时还需要recv等
    待接受所有客户端发送的数据,由于accept和recv都是阻塞IO,所以导致程序逻辑无法编写
  • 解决方法:
    • TCP并发服务器线程/进程模型:
      • 优点:实现简单
      • 缺点:资源消耗大,每个TCP连接都会分配一个线程任务
    • TCP并发服务器多路复用模型

2.Linux系统的4种I/O模型

  • 阻塞I/O
    • 效率高,数据没来时,CPU阻塞等待,不占用CPU资源
  • 非阻塞I/O
    • 效率低,需要轮询是否有IO事件发生
  • 异步I/O
    • 当内核监测到有IO事件发生时,主动向应用层上报信号事件
  • 多路复用I/O
    • 用一个函数接口监听多个文件描述符是否产生IO事件,只要其中一个产生事件,则不再
      阻塞,用户可以处理对应的事件
    • select(4个缺点)
      • select监听的文件描述符集合是一个数组,是有上限的(一般为1024)
      • select监听的文件描述符集合在应用层,当事件发生需要产生一次内核层向应
        用层数据的拷贝,会产生资源开销
      • select只能工作在水平触发模式(低速模式)
      • select必须将所有在文件描述符集合中的元素找一遍才能找到产生事件的文件
        描述符
    • poll(3个缺点)
      • poll监听的事件集合在链表中,没有上限的限制
      • 其余与select特点相同(3个缺点)
    • epoll
      • 没有文件描述符上限的限制
      • epoll创建一张内核监听的事件表,所以事件表在内核中,无需与应用层交互效
        率高
      • epoll可以工作在水平触发(默认)和边沿触发模式(EPOLLET)
      • epoll可以将产生事件的所有文件描述符返回,而不需要手动检测所有文件符是
        否有事件发生

3.函数接口

1.fcntl

int fcntl(int fd, int cmd, ... /* arg */ );

功能:向文件描述符发送cmd命令

参数:

fd:文件描述符

cmd:

F_GETFL 获得属性

F_SETFL 设置属性

返回值:

成功返回0

失败返回-1

2.select

int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

功能:监听文件描述符集合中是否有事件发生

参数:

nfds:最大的文件描述符+1

readfds:读文件描述符集合

writefds:写文件描述符集合

execptfds:其余文件描述符集合

timeout:超时时间,传NULL表示一直阻塞

返回值:

成功返回产生事件的文件描述符个数

失败返回-1

如果超时仍然没有事件发生返回0

void FD_CLR(int fd, fd_set *set);

功能:将文件描述符fd从文件描述符集合中删除

int FD_ISSET(int fd, fd_set *set);

功能:判断fd是否仍在文件描述符集合中

void FD_SET(int fd, fd_set *set);

功能:将fd加入文件描述符集合中

void FD_ZERO(fd_set *set);

功能:将文件描述符集合清零

3.poll

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

功能:监听事件集合中的事件是否发生

参数:

fds:监听事件集合的数组首地址

nfds:事件数组的元素个数

timeout:超时时间, -1 一直阻塞直到事件发生

返回值:

失败返回-1

成功返回产生事件的个数

时间达到没有事件发生返回0

4.epoll

int epoll_create(int size);

功能:创建一张内核监听的事件表

参数:

size:事件表的事件的个数

返回值:

成功返回文件描述符

失败返回-1

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

功能:向内核事件表中添加、修改、删除事件

参数:

epfd:内核事件表的文件描述符

op:EPOLL_CTL_ADD 添加事件

EPOLL_CTL_MOD 修改事件

EPOLL_CTL_DEL 删除事件

fd:操作的文件描述符

event:事件集合

返回值:

成功返回0

失败返回-1

int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);

功能:监听事件表中的事件

参数:

epfd:文件描述符

events:存放产生事件的空间的首地址

maxevents:数组的大小

timeout:超时时间

返回值:

成功返回产生事件的文件描述符个数

失败返回-1

时间达到没有事件产生返回0

相关推荐
2401_8685347811 分钟前
网络冗余设计
网络
well06121 小时前
Linux 文件相关底层知识
linux·运维·服务器
wangbing11251 小时前
开发指南148-WebSocket-前端查报文
网络·websocket·网络协议
ESDWAN1 小时前
企业跨境网络合规建设指南:从线路选择到数据出境的全流程方案
网络·架构
库拉镜像AI牛牛2 小时前
漫剧工作室量产方案:依托知漫剧 AI 短剧降本增效
大数据·服务器·前端·人工智能·语音识别
wuyk5552 小时前
《WiFi 嵌入式物联网开发全套实战》| 第 30 章 WiFi 抗干扰、抗闪断、网络抖动过滤量产策略
网络
不会就选b2 小时前
Linux之TCP<2>
linux·网络·tcp/ip
沫璃染墨2 小时前
《从零入门Linux系统篇(五十八):线程篇·十一——线程安全与死锁详解:从可重入到多锁管理》
linux·服务器·开发语言·c++·驱动开发·安全·架构
姜鱼问生3 小时前
宝塔面板优雅下线:先 stop 再 disable 再 rm
运维·服务器
闭包不眠3 小时前
PDF文字提取交付前该检查什么
运维·服务器·图像处理·人工智能·计算机视觉·pdf