I/O多路转接
telnet如何实现多输入输出?
select
poll
代码演示
select
/*************************************************************************
> File Name: 1.select.c
> Mail: 1136984246@qq.com
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int main(void) {
fd_set rfds; // 定义一个用于检测输入是否就绪的文件描述符集合
struct timeval tv;
int retval;
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds); // 集合初始化为空
FD_SET(0, &rfds); // 把标准输入添加到rfds集合中
// FD_SETSIZE : 1024;
// 微妙级精度;可为,1.一直阻塞 2.不阻塞 3.指定时间
tv.tv_sec = 5;
tv.tv_usec = 0;
// rfds将返回就绪的集合,循环调用要重新初始化
// 只对标准输入感兴趣,定时5s
retval = select(1, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */
// EBADF, EINTR
if (retval == -1)
perror("select()");
// 返回就绪态文件描述符的个数
else if (retval)
printf("Data is available now.\n");
/* FD_ISSET(0, &rfds) will be true. */
// 超时,清空3个文件描述符集合
else
printf("No data within five seconds.\n");
exit(EXIT_SUCCESS);
}
poll
/*************************************************************************
> File Name: 1.poll.c
> Mail: 1136984246@qq.com
************************************************************************/
#include <stdio.h>
#include <poll.h>
#include <sys/time.h>
#include <stdlib.h>
int main() {
struct pollfd fds[2]; // 一个文件文件描述符集合,非3组
fds[0].fd = 0; // 对“标准输入”文件描述符感兴趣
fds[0].events = POLLIN; // 对“可读数据”感兴趣
fds[0].revents = 0; // 初始化;revents返回实际发生的事件
fds[1].fd = -1; // 两种方法:关闭单个文件描述符,revents返回0
// fds[1].events = 0; // 表示对某事不感兴趣
// 阻塞到5000ms, 注意select和poll只告诉I/O是否阻塞(是否就绪),无法告知数据是否传输成功
int retval = poll(fds, 2, 5000);
// 错误
if (retval == -1) {
perror("poll");
exit(1);
} else if (retval == 0) {
printf("Time out!\n");
} else if (retval > 0) {
// select 对一个文件描述符计数多次,poll只统计一次(对于一个文件描述符多种事件的情况)
printf("[%d] fds is ready!\n", retval);
}
printf("fds[0].revents = %d\n", fds[0].revents);
printf("fds[1].revents = %d\n", fds[1].revents);
return 0;
}
思考
- 对于C/S模型,多客户端模型,
select
,epoll
,poll
的框架有什么不同?