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

相关推荐
nxb5562 小时前
haproxy算法,ip透传,自定义haproxy错误页面
运维·服务器
黑桃小柒75 小时前
小,最终显示为TCP WINDOW FULL,TCP ZeroWindow。 仔细分析了下LWIP源码,还以为是内存管理出了问题,跟 ...
网络·网络协议·tcp/ip
网络研究院6 小时前
LastPass 发布紧急安全预警:针对主密码的活跃网络钓鱼攻击正在进行中
网络·安全·黑客·攻击·漏洞·风险·钓鱼
便利店10247 小时前
TCP 为什么有时故意跑不快?拥塞控制与滑动窗口一次讲清
服务器·网络协议·tcp·拥塞控制
向夏威夷 梦断明暄8 小时前
【高效管理token成本】OpenClaw精细化分库管理memory以减少token成本的方案的可行性研究
网络
杨某不才8 小时前
如何能让Linux服务器对shell 终端 + sftp 文件传输长期保活
linux·运维·服务器
vance048 小时前
免费Cloudflare隧道隐藏公网IP
linux·tcp/ip·github
三言老师9 小时前
文本工具组合统计服务器日志数据
linux·运维·服务器
m0_743697599 小时前
DNS服务器
运维·服务器
酷可达拉斯10 小时前
Linux操作系统-免密登录远程操作系统
linux·运维·服务器·网络·云计算