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 把目录下的文件复制到某一目录,修改权限,可命 ...
随机推荐
- ArcGIS for Android_离在线一体化核心技术基本流程
核心思想: a.数据首先存储于ArcSDE中,要素添加GlobleID,图层数据启用数据归档或开启版本化.b.然后将ArcSDE数据库托管于ArcGIS for Server作为数据存储.c.在Arc ...
- 使用PHP将长文章分页
如何分页 手动分页:一般在编辑内容时加入特殊分页标记,如{pages},提交后,PHP程序会根据分页符处理分页,生成不同的静态页面.这种分页方法分页准确,但是需要人工手动添加分页符,工作量大. 自动分 ...
- dede channel 增加limit(属性)功能
dede channel 标签添加 limit(属性)功能 在用dede建站的时候,往往会需要用到一些需要自定义的普通需求,今天在这里介绍channel的limit功能,有时候我们需要调用中间部分数据 ...
- iOS9 URL Schema 白名单 微信
近期苹果公司iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查其他应用是否安装. 受此影响,当你的应用在 ...
- python 使用总结
本人原来是编写java的,后来转到编写ios之后,最后又来编写python了.相对于其他的一些开发人员来说,我精通的语言还是比较杂的. 这里将几个语言进行类比,比较一些个人的看法的东西. 首先obje ...
- IOS tableview下拉刷新上拉加载分页
http://code4app.com/ios/快速集成下拉上拉刷新/52326ce26803fabc46000000 刷新没用用插件,加载使用的MJ老师的插件. - (void)viewDidLoa ...
- java序列化知识整理
1. 什么是序列化? 序列化就是只把一个对象串行化成一个字节流,用于网络传输或者持久化. 2. 序列化的使用场景? a). 把内存中的对象持久化到文件或者数据库中: b). 对象在网络上传输. 3. ...
- Mongodb和Hive详细对比
本文主要用于分析在大数据场景下Mongodb和Hive的优缺点: 支持的数据类型 支持的查询 支持的数据量 性能优化手段
- Maven安装最佳实践(Windows平台)
第一步:下载maven,解压缩. 在maven官网下载maven文件,这里我下载的是"apache-maven-2.2.1-bin.zip",如果需要maven的源代码,可以选择下 ...
- DP(Dynamic programming)——尽力学习之中(2016 HUAS ACM 暑假集训-5)
这周不打算按照以往的方式更新博客,而是采用整体的方式.一是因为学的太少,没东西写:二是这篇博客会经常更新的.如题,DP——尽力学习之中. ------------------------------- ...