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

相关推荐
Geeys11 分钟前
拼多多新店快速起流量完整实操
大数据·网络·人工智能
玖玥拾1 小时前
C# 语言进阶(十四)Unity UI界面开发 + 网络消息联动
服务器·开发语言·网络·ui·unity·c#·游戏引擎
hbugs0011 小时前
PNETLab vs EVE-NG Pro 流量洞察功能底层架构技术白皮书
网络·架构·eve-ng·bpf·流量洞察
巴啦啦小魔仙变身2 小时前
SIGINT = Signal Interrupte
linux·服务器·python
不会C语言的男孩2 小时前
TCP通信可视化工具,含下载地址
服务器·网络·安全
五五六六05243 小时前
2026盘古石杯初赛
网络
TDengine (老段)3 小时前
TDengine SMA 索引 — 块级/文件级统计索引
android·大数据·服务器·数据库·人工智能·时序数据库·tdengine
玖玥拾3 小时前
C# 语言进阶(十三)网络 DLL 库分层设计
服务器·开发语言·网络·网络协议·c#
大师兄66683 小时前
HarmonyOS7 HTTP 网络请求封装:统一拦截器实战
网络·网络协议·http·arkui·harmonyos7·实战讲解
hbugs0013 小时前
BPF 表达式检查器:一款免费开源的 Wireshark 捕获过滤器语法检查与可视化构建工具
网络·测试工具·开源·eve-ng·bpf