select(Linux 编程)

select系统调用时用来让我们的程序监视多个文件句柄的状态变化的。程序会停在select这里等待,直到被监视的文件句柄有一个或多个发生了状态改变。
关于文件句柄,其实就是一个整数,通过socket函数的声明就明白了:
int socket(int domain, int type, int protocol);
我们最熟悉的句柄是0、1、2三个,0是标准输入,1是标准输出,2是标准错误输出。0、1、2是整数表示的,对应的FILE *结构的表示就是stdin、stdout、stderr。

继续上面的select,就是用来监视某个或某些句柄的状态变化的。select函数原型如下:
int select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
函数的最后一个参数timeout是一个超时时间值。其类型是struct timeval *,即一个struct timeval结构的变量的指针,所以我们在程序里要声明一个struct timeval tv;然后把变量tv的地址&tv传递给select函数。struct timeval结构如下:
struct timeval
{
      long tv_sec;  //seconds
      long tv_usec; //microseconds
};
第2、3、4三个参数是一样的类型;fd_set *,即我们在程序里要申请几个fd_set类型的变量,比如rdfds,wtfds,exfds,然后把这个变量的地址&rdfds,&wtfds,&exfds传递给select函数。这三个参数都是一个句柄的集合,第一个rdfds是用来保存这样的句柄的:当句柄的状态变成可读时系统就告诉select函数返回,同理第二个函数是指向有句柄状态变成可写时系统就会告诉select函数返回,同理第三个参数exfds是特殊情况,即句柄上有特殊情况发生时系统会告诉select函数返回。特殊情况比如对方通过一个socket句柄发来了紧急数据。如果我们程序里只想检测某个socket是否有数据可读,我们可以这样:
fd_set  rdfds;
struct timeval tv;
int ret;
FD_ZERO(&rdfds);
FD_SET(socket, &rdfds);
tv.tv_sec = 1;
tv.tv_uses = 500;
ret = select (socket + 1, %rdfds, NULL, NULL, &tv);
if(ret < 0) perror (“select”);
else if (ret = = 0) printf(“time out”);
else {
      printf(“ret = %d/n”,ret);
      if(FD_ISSET(socket, &rdfds)){
  /* 读取socket句柄里的数据 */
recv( );
}
}
注意select函数的第一个参数,是所有加入集合的句柄值的最大那个那个值还要加1.比如我们创建了3个句柄;
int sa, sb, sc;
sa = socket(……);
connect (sa,….);
sb = socket(….);
connect (sb,…);
sc = socket(….);
connect(sc,…);
FD_SET(sa, &rdfds);
FD_SET(sb, &rdfds);
FD_SET(sc, &rdfds);
在使用select函数之前,一定要找到3个句柄中的最大值是哪个,我们一般定义一个变量来保存最大值,取得最大socket值如下:
int maxfd = 0;
if(sa > maxfd) maxfd = sa;
if(sb > maxfd) maxfd = sb;
if(sc > maxfd) maxfd = sc;
然后调用select函数:
ret = select (maxfd+1, &rdfds, NULL, NULL,&tv);
同样的道理,如果我们是检测用户是否按了键盘进行输入,我们就应该把标准输入0这个句柄放到select里来检测,如下:
FD_ZERO(&rdfds);
FD_SET(0, &rdfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
ret = select (1, &rdfds,NULL,NULL,&tv);
if(ret < 0) perror(“select”);
else if (ret = = 0) printf (“time out/n”);
else{
      scanf(“%s”,buf);
}

时间: 2024-12-27 20:55:23

select(Linux 编程)的相关文章

求助 linux 编程 创建服务器

问题描述 求助 linux 编程 创建服务器 创建一个服务器 让多个终端连接并交互信息 最后用SIGUSR1关闭连接 用SIGUSR2记录连接终端的个数 解决方案 <linux高性能服务器编程>读书笔记linux网络编程多进程并发服务器Linux select TCP并发服务器与客户端编程

Linux编程中的while循环问题

我们先要理解while循环的意义,使用while循环的目的就是多次循环! while循环是根据while关键字后面指定的条件决定是否退出的循环的. 如果你希望执行一次命令就退出,那么无需用while循环,使用while就表示你需要多次循环,好了,我猜测下,你的问题是希望true的条件下,如何退出循环吧? 如果是的话,那么大概有如下几个方法. 1.while后的条件不是为true永远为真,而是指定一个条件,那么条件不满足就退出了. 例子如下: i=0 while ((i<10)) do echo

[综合面试] 牛人整理分享的面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结

感谢IT面试群 S-北京-陈磊 的整理分享. 基础篇:操作系统.计算机网络.设计模式 一:操作系统 1. 进程的有哪几种状态,状态转换图,及导致转换的事件. 2. 进程与线程的区别. 3. 进程通信的几种方式. 4. 线程同步几种方式.(一定要会写生产者.消费者问题,完全消化理解) 5. 线程的实现方式. (也就是用户线程与内核线程的区别) 6. 用户态和核心态的区别. 7. 用户栈和内核栈的区别. 8. 内存池.进程池.线程池.(c++程序员必须掌握) 9. 死锁的概念,导致死锁的原因. 10

linux网络编程-linux方面遇到的一个难题,希望大哥大姐帮忙解决下,小弟是菜鸟,刚学linux编程

问题描述 linux方面遇到的一个难题,希望大哥大姐帮忙解决下,小弟是菜鸟,刚学linux编程 /proc/进程号/statm包含了进程使用内存的信息,如[root@cs 9519]# more statm 18095 2094 1468 7 0 605 0 [root@cs 9519]# ps 9519PID TTY STAT TIME COMMAND9519 ? S 0:00 /usr/libexec/notification-daemonmore statm 18095 2094 1468

linux编程问题,expect脚本问题,急求

问题描述 linux编程问题,expect脚本问题,急求 #!/usr/bin/expect -f set IP [lindex $argv 0 ] spawn scp /root/.ssh/id_rsa.pub root@${IP}:/root/.ssh/ expect { "Are you sure you want to continue connecting*" { send "yesr"; exp_continue } 写了个脚本,大概是这样,但现在有个问

linux编程-关于RTAI中一段代码的意思,求解~

问题描述 关于RTAI中一段代码的意思,求解~ #ifdef RTAI rt_allow_nonroot_hrt();#elsemlockall(MCL_CURRENT | MCL_FUTURE);/* Xenomai non-root scheduling is coming soon! */#endif 解决方案 这是我在我的Linux编程中主函数看到的一段代码 这个是什么意思啊 主要不懂RTAI

linux编程-关于Linux的三个编程题,想了半天毫无头绪,感觉Linux编程好复杂。求大家帮助帮助我,谢谢。

问题描述 关于Linux的三个编程题,想了半天毫无头绪,感觉Linux编程好复杂.求大家帮助帮助我,谢谢. 1:子进程每隔一秒向文件写入信息,父进程每隔三秒读出子进程所写的信息并输出到屏幕. 2:模拟shell,设计一个交互式命令处理程序,注意对命令参数和环境参数的处理. 3:编写一个守护进程,实现功能为:每隔一秒,向当前目录下的hello文件里写入一行helloworld. 解决方案 Linux设备驱动编程之复杂设备驱动25岁了,是学linux运维还是编程好呢?求指点下 .. 解决方案二: 楼

c++-C与C++的区别仅在于OPP吗?linux 编程C++是不是么有C++接口,只是调用C接口吗?

问题描述 C与C++的区别仅在于OPP吗?linux 编程C++是不是么有C++接口,只是调用C接口吗? C与C++的区别仅在于OPP吗?linux 编程C++是不是么有C++接口,只是调用C接口吗? 解决方案 C和C++最大的区别当然是C++支持OOP,但是它们也有一些细节上的不同.比如C++支持模板.引用.命名空间等,C++ 11/14更是增加了Lambda表达式.类型推断.自动指针等等. 解决方案二: 不是的呀,c++库是跨平台的 解决方案三: C调用C++接口c++中调用c接口的问题Li

多线程-linux 编程 统计UDP报文

问题描述 linux 编程 统计UDP报文 监听目的端口为9090的 udp报文,要求如下: 1. 提取出报文源ip信息,并统计出各自的报文数 2. 针对每个源ip,统计各自的大报文数(大小超过1024B) 3. 这些信息条目按ip由小到大进行排列,可通过命令将信息显示出来,同时还可通过命令将信息写入result.txt文件(覆盖方式) 4. 提供命令能将指定的源ip的报文统计数清0 5. 能统计指定的源ip的报文速率,即每分钟的报文数 6. 使用多线程,信号量相关机制 (报文用发包软件构造,使

点评五款用于 Linux 编程的内存调试器

点评五款用于 Linux 编程的内存调试器 Credit: Moini 作为一个程序员,我知道我肯定会犯错误--怎么可能不犯错!程序员也是人啊.有的错误能在编码过程中及时发现,而有些却得等到软件测试了才能显露出来.然而,还有一类错误并不能在这两个阶段被解决,这就导致软件不能正常运行,甚至是提前终止. 如果你还没猜出是那种错误,我说的就是和内存相关的错误.手动调试这些错误不仅耗时,而且很难发现并纠正.值得一提的是,这种错误很常见,特别是在用 C/C++ 这类允许手动管理内存的语言编写的软件里. 幸