select函数简解:
selct 称之为多路复用IO,使用它可以让程序阻塞在select上,而非实际IO函数上. int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
nfds: fd_set描述符集中 {最大描述符+1}
readfds: 读描述符集
writefds: 写描述符集
exceptfds: 异常描述符集
timeout: 超时时间,1)当timeout为NULL时,select将阻塞到有读或写或异常描述符就绪才返回。
2)当timeout中tv_sec==0且tv_usec==0时,表示不等待,扫描一次马上返回。
3)当timeout中tv_sec!=0且tv_usec!=0时,表示在指定时间内没有就绪描述符就返回。函数返回0 注意:
1)正常情况下返回就绪描述符个数!
2)同时会将未就绪的描述符置零,所以select每次返回后我们都应将需用监听的描述符重新添加到描述符集中。
3)为了可移植,当设置了超时时间时也应当从新赋值。
4)使用select函数尽量不要与非系统IO混用 以下是对描述符集操作的函数:
void FD_CLR(int fd, fd_set *set);
从描述符集set中清除描述符fd int FD_ISSET(int fd, fd_set *set);
判断描述符fd 是否在描述符集set中,是,返回非0;否,返回0 void FD_SET(int fd, fd_set *set);
将描述符fd 添加到描述符集set中 void FD_ZERO(fd_set *set);
对描述符集进行清零,当我们新定义一个描述集时,最好使用此函数进行清零,
简单的服务器回射程序:

#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <strings.h> #include "common.h" #define SERV_PORT 10086 typedef struct sockaddr SA; int main(void)
{
int listenfd, connfd;
struct sockaddr_in cliaddr, servaddr;
socklen_t clientlen; if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
err_quit("socket error");
} bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(listenfd, (SA *)&servaddr, sizeof(servaddr)) < 0) {
err_quit("bind error");
} if (listen(listenfd, 5) < 0) {
err_quit("listen error");
} fd_set rfds, allfd;
int maxfd, maxi = -1; //method one:
//int maxfd;
//if ((maxfd = sysconf(_SC_OPEN_MAX)) < 0) {
// err_sys("sysconf error");
//}
//
//int clinet[maxfd];
//----------------------------------------------------- //method two:
//在sys/select.h中定义了一个FD_SETSIZE其表示fd_set描述符总数。
int client[FD_SETSIZE];
//----------------------------------------------------- int nready;
int i, nread;
int sockfd;
char buf[MAXLINE]; FD_ZERO(&allfd);
FD_SET(listenfd, &allfd);
maxfd = listenfd; for (i=0; i<FD_SETSIZE; ++i) {
client[i] = -1;
} for ( ; ; ) { rfds = allfd; nready = select(maxfd+1, &rfds, NULL, NULL, NULL);
if (nready < 0) {
err_quit("select error");
} if (FD_ISSET(listenfd, &rfds)) { #ifdef DEBUG
printf("have descriptor....\n");
#endif clientlen = sizeof(cliaddr);
connfd = accept(listenfd, (SA *)&cliaddr, &clientlen);
if (connfd < 0) {
err_quit("accept error");
} for (i=0; i<FD_SETSIZE; ++i) {
if (client[i] < 0) {
client[i] = connfd;
break;
}
} if (i == FD_SETSIZE) {
err_quit("too many clients");
} FD_SET(connfd, &allfd); if (connfd > maxfd) {
maxfd = connfd;
} if (i > maxi) {
maxi = i;
} if (--nready <= 0) {
continue;
}
} for (i=0; i<=maxi; ++i) {
if ((sockfd = client[i]) < 0) {
continue;
} if (FD_ISSET(sockfd, &rfds)) { #ifdef DEBUG
printf("fd: %d\n", sockfd);
#endif if ((nread = read(sockfd, buf, MAXLINE)) == 0) {
close(sockfd);
FD_CLR(sockfd, &allfd);
client[i] = -1;
} else {
if (write(sockfd, buf, nread) != nread) {
err_msg("fail to write...");
}
} if (--nready <= 0) {
continue;
}
}
}
} return EXIT_SUCCESS;
}

select函数实例代码的更多相关文章

  1. php header函数实例代码

    一个完美的演示PHP header()函数用法的完整代码. 其中介绍的refresh方法,比<META ……用起来更得心应手,应该是段不错的代码. <?php  /*** Function ...

  2. php全角字符转换为半角函数 实例代码

    PHP全角半角转换函数,把目前能找到的所有全角都列出来了一个个替换吧. 之前试过网上找的通过ASCII之类的字符替换,发现很多莫名其妙的问题.最后还是换成下面的字符替换方式了,把目前能找到的所有全角都 ...

  3. select函数详解(转)

    Select函数在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect. accept.recv或recvfrom这样的阻塞 ...

  4. php随机密码函数的实例代码

    php随机密码函数的入门例子 时间:2015-12-16 20:42:48来源:网络 导读:php生成随机密码的函数实例,php生成随机密码的函数,生成数字.大小写字母与特殊字符组合的随机密码.   ...

  5. select使用实例——str_cli函数(修订版)

    我们可以使用select函数重写http://www.cnblogs.com/nufangrensheng/p/3587962.html中的str_cli函数,这样服务器进程一终止,客户就能马上得到通 ...

  6. select 函数1

    Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect.accept.recv或recvfrom这样的阻塞程序( ...

  7. PHP读取超大文件的实例代码

    数据量大带来的问题就是单个文件很大,能够打开这个文件相当不容易,记事本就不要指望了,果断死机   去年年底的各种网站帐号信息的数据库泄漏,很是给力啊,趁机也下载了几个数据库,准备学学数据分析家来分析一 ...

  8. select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET

    http://hi.baidu.com/%B1%D5%C4%BF%B3%C9%B7%F0/blog/item/e7284ef16bcec3c70a46e05e.html select函数用于在非阻塞中 ...

  9. python迭代器与iter()函数实例教程

    python迭代器与iter()函数实例教程 发布时间:2014-07-16编辑:脚本学堂 本文介绍了python迭代器与iter()函数的用法,Python 的迭代无缝地支持序列对象,而且它还允许程 ...

随机推荐

  1. 练习四十六:列表排序,删除list中重复的元素

    方法一:使用集合set;将list直接转换为set a = [1,3,4,3,5,7] a = list(set(a)) print(a) 执行结果: [1, 3, 4, 5, 7] 方法二:直接排序 ...

  2. DB restore point and datagurad

    ######## 12.5.1 Flashing Back a Physical Standby Database to a Specific Point-in-Time The following ...

  3. postgresql 导出csv格式的数据后使用excel打开中文乱码的问题

    两种方法: 1>使用excel 的自文本导入功能,具体方法: 1) 打开 Excel 2) 执行“数据”->“自文本” 3) 选择 CSV 文件,出现文本导入向导 4) 选择“分隔符号”, ...

  4. 使用gulp构建工具

    之前一个demo中用的是grunt,照着grunt用到的插件找了下gulp的,总体使用还算顺畅,说实话并不觉得学习成本有降低什么的,差不多.不过也遇到一些问题: 1.gulp.dest()输出目录需要 ...

  5. C# String.Format方法

    一.定义String.Format是将指定的 String类型的数据中的每个格式项替换为相应对象的值的文本等效项. 如: (1)string p1 = "Jackie";strin ...

  6. FFmpeg编译i386 OSX 脚本

    话不多说, 直接上脚本 #!/bin/sh # directories PLATFORM="OSX" # FFmpeg脚本目录 SOURCE="ffmpeg-2.8.7& ...

  7. Vue通过状态为页面切换添加loading、为ajax加载添加loading

    以下方法需要引入vuex,另使用了vux的UI框架,ajax添加loading还引入了axios. 一.为页面切换添加loading. loading.js: import Vue from 'vue ...

  8. 零基础逆向工程28_Win32_02_事件_消息_消息处理函数

    1 第一个图形界面程序 步骤1:创建Windows应用程序 选择空项目 步骤2:在新建项窗口中选C++代码文件 创建一个新的cpp文件 步骤3:在新的cpp文件中添加:#include <Win ...

  9. NetBeans切换其他界面风格

    NetBeans是一款优秀的IDE,但是界面过亮,让我从使用以来就又爱又恨,经过一番摸索,测试出一款扩展软件 个人挺喜欢的分享出来 废话不多说下面教程: 1.安装NetBeans: 2.下载外观包ja ...

  10. Thymeleaf的模板使用介绍

    参考网址: https://blog.csdn.net/hry2015/article/details/73476973 先定义一个html文件, 如下: 文件路径: templates/templa ...