网络: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

相关推荐
bloglin999995 小时前
scp、rsync远程文件同步
linux·运维·服务器
克莱因3585 小时前
思科 Cisco 标准ACL
网络·路由
迦南的迦 亚索的索5 小时前
LINUX环境
linux·运维·服务器
yuanjj885 小时前
linux下调试域格CLM920 NC5等9x07平台模块 QMI拨号
linux·运维·服务器
IMPYLH5 小时前
Linux 的 printenv 命令
linux·运维·服务器·bash
SilentSamsara5 小时前
SSH 远程管理:密钥登录 + 隧道转发,一次性配置好
linux·运维·服务器·ubuntu·centos·ssh
资深数据库专家6 小时前
总账EBS 应用服务器1 的监控分析
java·网络·数据库
2501_945837436 小时前
OpenClaw:开启 “行动 AI“ 新纪元,从聊天机器人到自主智能体的范式革命
服务器
阿正的梦工坊6 小时前
拦截网络请求:一种更优雅的数据获取方式
网络·okhttp
阿巴~阿巴~7 小时前
Git版本控制完全指南:从入门到实战(简单版)
linux·服务器·git