UNIX网络编程-Select模型学习
1、相关接口介绍
1.1 select
----------------------------------------------------------------------
#include <sys/select.h>
#include <sys/time.h>
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout);
返回:准备好描述字的正数目,0—超时,-1—出错。
----------------------------------------------------------------------
参数说明:
maxfdp1: 制定要检查的描述符的个数,实际应用中传入最大描述符加1,表明要检查0到最大描述符中间的所有描述符。
readset、writeset、exceptset: 这三个参数都是值-结果参数,传入的是应用程序想让内核检查的套接字集合,传出的是内核检查过的可进行操作的套接字集合。
timeout: 超时设置,NULL表示一直等,直到有一个套接字准备好I/O时才返回,将秒和微秒两个字段都设置为0表示不等待,立即返回。
1.2 fd_set
fd_set: 存放套接字的集合。
有四个操作fd_set的宏,分别是:
void FD_ZERO(fd_set *fdset);
void FD_SET(int fd, fd_set *fdset);
void FD_CLR(int fd, fd_set *fdset);
void FD_ISSET(int fd, fd_set *fdset);
FD_SET设置文件描述符集fdset中对应于文件描述符fd的位(设置为1)
FD_CLR清除文件描述符集fdset中对应于文件描述符fd的位(设置为0)
FD_ZERO清除文件描述符集fdset中的所有位(既把所有位都设置为0)。
使用这3个宏在调用select前设置描述符屏蔽位,在调用select后使用FD_ISSET来检测文件描述符集fdset中对应于文件描述符fd的位是否被设置。
1.3 timeval
是一个表示时间的结构体:
- struct timeval
- {
- long tv_sec; /* seconds */
- long tv_usec; /* microseconds */
- };
2、select I/O复用模型的工作流程
2.1 初始化的时候将要检查的socket放入事先定义好的fd_set集合中;
2.2通过调用select函数来获取可读、可写的socket集合;
2.3 获取集合后先检查监听socket,看是否有新的socket连接,若有,则将新的socket添加到集合中准备下一次的扫描;
2.4扫描检查过的集合,对相应的socket进行读写操作;
以下是一个使用select的简单demo,可以处理多个客户端同时跟服务端通信。
3、一个简单的Echo Server
- #include <stdio.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <strings.h>
- #define PORT 8080
- #define LISTENQ 5
- #define MAXLINE 1024
- #define IS_ERROR(condition) \
- if(condition) \
- { \
- printf("Error in func[%s] and line[%d]!\n", \
- __PRETTY_FUNCTION__, __LINE__); \
- return ; \
- }
- int main(int argc, char *argv[])
- {
- struct sockaddr_in addrSer;
- struct sockaddr_in addrCli;
- int listenSock;
- int connSock;
- int clientSock[FD_SETSIZE];
- int maxSock; //the max fd
- int sumSock; //sum of client sockets - 1
- int nCliLen; //len of addrCli
- int nReady; //the num of ready sockets
- fd_set allset;
- fd_set rset;
- char buf[MAXLINE];
- int nRet;
- int i;
- /*create listen socket*/
- listenSock = socket(AF_INET, SOCK_STREAM, );
- IS_ERROR(listenSock == -);
- /*bind listen port*/
- bzero(&addrSer, sizeof(addrSer));
- addrSer.sin_family = AF_INET;
- addrSer.sin_addr.s_addr = htonl(INADDR_ANY);
- addrSer.sin_port = htons(PORT);
- nRet = bind(
- listenSock,
- (struct sockaddr *)&addrSer,
- sizeof(struct sockaddr_in)
- );
- IS_ERROR(nRet == -);
- /*listen port*/
- nRet = listen(listenSock, LISTENQ);
- IS_ERROR(nRet == -);
- /*init*/
- maxSock = listenSock;
- sumSock = -;
- /*Init socket array*/
- for (i=; i<FD_SETSIZE; ++i)
- {
- clientSock[i] = -;
- }
- /*Init fd_set*/
- FD_ZERO(&allset);
- FD_SET(listenSock, &allset);
- /*request*/
- while ()
- {
- rset = allset;
- nReady = select(maxSock+, &rset, NULL, NULL, NULL);
- /*accept*/
- if (FD_ISSET(listenSock, &rset))
- {
- nCliLen = sizeof(addrCli);
- connSock = accept(listenSock, (struct sockaddr *)&addrCli, &nCliLen);
- for (i=; i<FD_SETSIZE; ++i)
- {
- if (clientSock[i] < )
- {
- clientSock[i] = connSock;
- break;
- }
- }
- if (i == FD_SETSIZE)
- {
- printf("too many clients!\n");
- return ;
- }
- FD_SET(connSock, &allset);
- maxSock = (maxSock < connSock) ? connSock : maxSock;
- sumSock = (sumSock < i) ? i : sumSock;
- if (--nReady <= )
- {
- continue;
- }
- }
- /*send and recv*/
- for (i=; i<=sumSock; ++i)
- {
- if (clientSock[i] < )
- {
- continue;
- }
- if (FD_ISSET(clientSock[i], &rset))
- {
- nRet = recv(clientSock[i], buf, MAXLINE, );
- if (nRet == || nRet == -)
- {
- printf("read sock %d err, nRet = %d!\n", clientSock[i], nRet);
- close(clientSock[i]);
- FD_CLR(clientSock[i], &allset);
- clientSock[i] = -;
- }
- else if (- == send(clientSock[i], buf, nRet, ))
- {
- printf("write sock %d err!\n", clientSock[i]);
- close(clientSock[i]);
- FD_CLR(clientSock[i], &allset);
- clientSock[i] = -;
- }
- if (--nReady <= )
- {
- break;
- }
- } //if (FD_ISSET(clientSock[i], &rset))
- } //for (i=0; i<=sumSock; ++i)
- } //while(1)
- return ;
- }
UNIX网络编程-Select模型学习的更多相关文章
- UNIX网络编程-Poll模型学习
1.相关接口介绍 1.1 poll ---------------------------------------------------------------------- #include &l ...
- UNIX网络编程——select函数的并发限制和 poll 函数应用举例
一.用select实现的并发服务器,能达到的并发数,受两方面限制 1.一个进程能打开的最大文件描述符限制.这可以通过调整内核参数.可以通过ulimit -n来调整或者使用setrlimit函数设置, ...
- UNIX网络编程——网络I/O模型
在学习UNIX网络编程的时候.一開始分不清 同步 和 异步,所以还是总结一下,理清下他们的差别比較好. IO分类 IO依据对IO的调度方式可分为堵塞IO.非堵塞IO.IO复用.信号驱动IO.异步IO. ...
- 【unix网络编程第三版】阅读笔记(五):I/O复用:select和poll函数
本博文主要针对UNP一书中的第六章内容来聊聊I/O复用技术以及其在网络编程中的实现 1. I/O复用技术 I/O多路复用是指内核一旦发现进程指定的一个或者多个I/O条件准备就绪,它就通知该进程.I/O ...
- UNIX网络编程——使用select函数编写客户端和服务器
首先看原先<UNIX网络编程--并发服务器(TCP)>的代码,服务器代码serv.c: #include<stdio.h> #include<sys/types.h> ...
- Unix网络编程中的五种I/O模型_转
转自:Unix网络编程中的的五种I/O模型 下面主要是把unp第六章介绍的五种I/O模型. 1. 阻塞I/O模型 例如UDP函数recvfrom的内核到应用层.应用层到内核的调用过程是这样的:首先把描 ...
- 《UNIX网络编程 卷1》之"学习环境搭建"(CentOS 7)
<UNIX网络编程 卷1>的源码可以从www.unpbook.com下载得到.解压之后的目录为unpv13e. 详细步骤 编译 进入unpv13e目录,按如下步骤编译: ./configu ...
- UNIX网络编程 第6章 I/O复用:select和poll函数
UNIX网络编程 第6章 I/O复用:select和poll函数
- 记录一次配置unix网络编程环境的过程和遇到的问题
记录一次搭建unix网络编程环境过程中遇到的问题和总结 计算机环境虚拟机 linuxmint-18-xfce-64bit 1.打开unix网络编程.iso 把目录下的文件复制到某一目录,修改权限,可命 ...
随机推荐
- Spring Application Event Example
Spring Application Event 项目结构 工程下载 https://github.com/xiaoheike/SpringApplicationEventExample.git Sp ...
- Java中的List操作
1. 数组转List String[] arr={"1","2","3"}; List<String> list = Array ...
- netezza 数据库 取 季初 季末 时间
-- 取季初那一天 select date_trunc( 'quarter',cast('20150820' as date)) -- 取季末那一天 select add_months(date_tr ...
- Django 创建APP简单步骤
yum install epel-releaseyum install python34yum install python-pippip install django django-admin st ...
- 启动odoo-10.0成功,但是访问时出错
启动odoo-10.0显示成功 2017-01-05 06:49:48,211 532 INFO ? odoo: Odoo version 10.02017-01-05 06:49:48,211 53 ...
- HTML5学堂,感谢您一年的陪伴(上)
在HTML学堂将满一周岁之际,感谢再过去的一年里支持和关注它的每一个小伙伴.有了你们的支持,HTML5学堂才能更好的走下去.我们将会把这一年的积累重新体现在HTML5学堂的官网上.HTML5学堂将会全 ...
- quick sort 的简化实现
Pivot 随机选取意义不大 第一种方法使用随机pivot,使得尽可能平均二分序列,而实际上一般来说需要排序的集合往往是乱序的,无需重新生成随机数作为pivot,大可使用固定位置的数作为pivot,这 ...
- Android AsyncTask 简单用法
简介 AsyncTask 是一个轻量级的异步处理类.使用是需继承自该类.可以方便的执行异步任务并且在将进度显示在UI上. 注意事项 AsyncTask只适合处理轻量级的任务即耗时几秒或者几十秒的任务. ...
- StackGAN: Text to Photo-realistic Image Synthesis with Stacked Generative Adversarial Networks 论文笔记
StackGAN: Text to Photo-realistic Image Synthesis with Stacked Generative Adversarial Networks 本文将利 ...
- nodemon配置文件简单整理
文件名称nodemon.json 内容如下: { "restartable":"rs",//重启的命令,默认是 rs "ignore":[& ...