admin 管理员组文章数量: 887021
网络通信
多路复用:
使用一个进程(且只有主线程)同时监控若干个文件描述符读写情况,这种读写模式称为多路复用
多用于TCP的服务端,用于监控客户端的连接和数据的发送
优点:不需要频繁地创建、销毁进程,从而节约了内存资源、时间资源,也避免了进程之间的竞争、等待
缺点:要求单个客户端的任务不能太过于耗时,否则其它客户端就会感知到卡顿
适合并发量高、但是任务量短小的情景,例如:Web服务器
select:
fd_set 是文件描述符的集合,使用以下函数操作:
void FD_CLR(int fd, fd_set *set);
功能:从集合set中删除fd文件描述符
int FD_ISSET(int fd, fd_set *set);
功能:判断集合set中是否存在fd文件描述符
void FD_SET(int fd, fd_set *set);
功能:向集合set中添加fd文件描述符
void FD_ZERO(fd_set *set);
功能:清空集合set
int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
功能:同时监控多个文件描述符的读、写、异常操作
nfds:被监控的文件描述符中的最大值+1
readfds:监控读操作的文件描述符集合
writefds:监控写操作的文件描述符集合
exceptfds:监控异常操作的文件描述符集合
timeout:设置超时时间
NULL 一直阻塞,直到某个文件描述符发生了变化
0秒0微秒 非阻塞
大于0 等待超时时间,超时返回0
struct timeval {
long tv_sec; /* seconds */ 秒
long tv_usec; /* microseconds */ 微秒
};
返回值:监控到发生相关操作的文件描述符的个数,超时返回0,错误返回-1
注意:
readfds、writefds、exceptfds 这三个集合参数既是输入也是输出,调用select时这三个集合需要存储被监控的文件描述符,
当由于有文件描述符发生了相应的操作的人导致函数返回时,这三个集合中存储了这些文件描述符并返回给调用者
select:设计不合理的地方
1、每次调用select都需要向它重新传递被监控的文件描述符集合
2、调用结束后如果想直到具体是哪个文件描述符发生了相关操作,必须对所有被监控的文件描述符进行一遍测试
select的优点:
它是最早的多路复用函数,几乎所有的操作系统都支持,兼容性很高
pselect:
int pselect(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
功能:大致与select一样
区别:
1、超时时间的结构类型不同
struct timespec {
long tv_sec; /* seconds */ 秒
long tv_nsec; /* nanoseconds */ 纳秒
};
2、pselect监控时可以通过sigmask参数设置要屏蔽的信号,可以保障pselect监控时不受这些信号干扰
共同点:本质上与select差别不大、select的缺点篇select也是一样的,只是个别功能有所增强而已
poll:
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
fds:struct pollfd结构变量数组
struct pollfd {
int fd; /* file descriptor */ 被监控的文件描述符
short events; /* requested events */ 想要监控的事件
short revents; /* returned events */ 实际监控到的事件
POLLIN 普通优先级的读事件
POLLPRI 高优先级的读事件
POLLOUT 普通优先级的写事件
POLLRDHUP 对方socket关闭
POLLERR 错误事件
POLLHUP 对方挂起
POLLNVAL 非法描述符
};
nfds:数组的长度
timeout:超时时间 按毫秒赋值 1000毫秒=1秒
返回值:监控到发生相关操作的描述符的个数,超时返回0,错误返回-1
epoll:
#include <sys/epoll.h>
int epoll_create(int size);
功能:创建一个epoll的内核对象,该对象可以管理、保存被监控的描述符
size:epoll对象管理描述符的数量
返回值:epoll对象的描述符
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
功能:控制epoll对象,添加、删除描述符
epfd:epoll对象的描述符
op:
EPOLL_CTL_ADD 添加监控的描述符
EPOLL_CTL_MOD 修改要监控的描述符的事件
EPOLL_CTL_DEL 删除监控的描述符
fd:
要操作的描述符
event:要监听的事件
struct epoll_event {
uint32_t events; /* Epoll events */ 要监控事件,参考poll
epoll_data_t data; /* User data variable */
};
typedef union epoll_data {
void *ptr;
int fd; // 产生事件的描述符
uint32_t u32;
uint64_t u64;
} epoll_data_t;
返回值:成功0 失败-1
int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
功能:监控文件描述符,并返回发生事件的描述符
epfd:epoll对象的描述符
events:输出型参数 用于获取发生事件的描述符
maxevents:可以返回的事件数目的最大值
timeout: 超时时间
返回值:监控到发生相关操作的描述符的个数,超时返回0,错误返回-1
epoll优点:
1、只需要拷贝一次待监控的描述符
2、会把发生事件的描述符返回,不需要遍历所有的描述符,大大地节约时间
3、编程结构更加简约
epoll的条件触发和边缘触发:
条件触发:当文件缓冲区中有需要读取的数据时就会触发事件,类似于键盘
边缘触发:当数据发送时触发一次事件
把监控的事件增加设置为EPOLLET,类似于鼠标
优点:大大地降低事件触发的次数,在某些只需要处理一次事件即可的情境下能够提高效率
本文标签: 网络通信
版权声明:本文标题:网络通信 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1686747870h32475.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论