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

相关推荐
stanlyYP2 小时前
服务器openclaw操作
运维·服务器
HealthScience2 小时前
内网服务器怎么连接外网
运维·服务器
Hns.2 小时前
SSH 端口转发IP请求
运维·tcp/ip·ssh
tctasia2 小时前
当原创IP遇上3D打印:一场关于“技术如何赋能创意落地”的深度讨论
服务器·tcp/ip·3d
海域云-罗鹏3 小时前
Token的本质是算力资源,企业生产Token的服务器托管与数据中心部署指南
运维·服务器·人工智能
cjy0001113 小时前
RustDesk搭建公网中继服务器远控内网机器(完整版)
运维·服务器
马猴烧酒.3 小时前
【面试八股|操作系统】操作系统常见面试题详解笔记
java·linux·服务器·网络·数据结构·算法·eclipse
哈__3 小时前
Linux 部署 RocketMQ 实操:从内网到公网的完整落地心得
linux·服务器·rocketmq
薛定谔的悦3 小时前
《储能系统中的故障定位》
java·服务器·前端