免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: luokeleee
打印 上一主题 下一主题

请教socket编程里的select知识 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2010-07-14 09:44 |只看该作者
如果对readfds、writefds或exceptfds中任一个组类不感兴趣,可将它置为空NULL。
   在winsock.h头文件中共定义了四个宏来操作描述字集。FD_SETSIZE变量用于确定一个集合中最多有多少描述字(FD_SETSIZE缺省值为64,可在包含winsock.h前用#define FD_SETSIZE来改变该值)。对于内部表示,fd_set被表示成一个套接口的队列,最后一个有效元素的后续元素为INVAL_SOCKET。宏为:
   FD_CLR(s,*set):从集合set中删除描述字s。
   FD_ISSET(s,*set):若s为集合中一员,非零;否则为零。
   FD_SET(s,*set):向集合添加描述字s。
   FD_ZERO(*set):将set初始化为空集NULL。
   timeout参数控制select()完成的时间。若timeout参数为空指针,则select()将一直阻塞到有一个描述字满足条件。否则的话,timeout指向一个timeval结构,其中指定了select()调用在返回前等待多长时间。如果timeval为{0,0},则select()立即返回,这可用于探询所选套接口的状态。如果处于这种状态,则select()调用可认为是非阻塞的,且一切适用于非阻塞调用的假设都适用于它。举例来说,阻塞钩子函数不应被调用,且WINDOWS套接口实现不应yield。

返回值:
   select()调用返回处于就绪状态并且已经包含在fd_set结构中的描述字总数;如果超时则返回0;否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。

错误代码:
   WSANOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()。
   WSAENETDOWN:WINDOWS套接口实现检测到网络子系统失效。
   WSAEINVAL:超时时间值非法。
   WSAEINTR:通过一个WSACancelBlockingCall()来取消一个(阻塞的)调用。
   WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。
   WSAENOTSOCK:描述字集合中包含有非套接口的元素。

详细出处参考:http://www.itqun.net/content-detail/70767.html

论坛徽章:
0
22 [报告]
发表于 2010-07-14 09:47 |只看该作者
范例 :

sock= socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in addr;     //告诉sock 应该再什么地方licence
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_port=htons(11111);  //端口啦
addr.sin_addr.s_addr=htonl(INADDR_ANY);        //在本机的所有ip上开始监听

bind (sock,(sockaddr *)&addr,sizeof(addr));//bind....

listen(sock,5);                   //最大5个队列

SOCKET socka;                    //这个用来接受一个连接
fd_set rfd;                     // 描述符集 这个将用来测试有没有一个可用的连接
struct timeval timeout;

FD_ZERO(&rfd);                     //总是这样先清空一个描述符集

timeout.tv_sec=60;                //等下select用到这个
timeout.tv_usec=0;

u_long ul=1;

ioctlsocket(sock,FIONBIO,&ul);    //用非阻塞的连接

//现在开始用select
FD_SET(sock,&rfd);    //把sock放入要测试的描述符集 就是说把sock放入了rfd里面 这样下一步调用select对rfd进行测试的时候就会测试sock了(因为我们将sock放入的rdf) 一个描述符集可以包含多个被测试的描述符,
if(select(sock+1,&rfd,0,0, &timeout)==0)
{//这个大括号接上面的,返回0那么就超过了timeout预定的时间

//处理....

}

if(FD_ISSET(sock,&rfd))
{      //有一个描述符准备好了

socka=accept(sock,0,0);     //一个用来测试读 一个用来测试写

FD_ZERO(&rfd);

FD_ZERO(&wfd);

FD_SET(socka,&rfd);//把socka放入读描述符集

FD_SET(sockb,&rfd);//把sockb放入读描述符集

FD_SET(socka,&wfd);把socka放入写描述符集

FD_SET(sockb,&wfd);把sockb放入写描述符集

if(SOCKET_ERROR!=select(0,&rfd,&wfd,0,0))      //测试这两个描述符集,永不超时 其中rfd只用来测试读 wfd只用来测试写

{      //没有错误

if(FD_ISSET(socka,&rfd))    //socka可读

{...}

if(FD_ISSET(sockb,&rfd)   //sockb可读

{...}

if(FD_ISSET(socka,&wfd) //socka 可写

{...}

if(FD_ISSET(sockb,&wfd) //sockb可写

{...}

}

详细出处参考:http://www.itqun.net/content-detail/70767.html

论坛徽章:
0
23 [报告]
发表于 2010-07-14 10:00 |只看该作者
回复 19# rain_fish


    是啊,我的进度安排很快,我已经开始学习跨平台的编程了,以前看过select的程序,寻思就一个函数,就过去了。后来到跨平台的时候编程才发现,以前学的socket有好多东西都理解的不够深入,就在网上发帖子,请求大家的帮助了。刚才把select的过程总结了总结,给我老师汇报了一下,老师说:恩,大概就应该是这个样子。^_^,很高兴,有种从小菜鸟成长成为大菜鸟的感觉,呵呵O(∩_∩)O~   谢谢您和大家的帮助,一起分享我的喜悦吧O(∩_∩)O~

论坛徽章:
0
24 [报告]
发表于 2010-07-14 10:01 |只看该作者
回复 23# luokeleee

恭喜恭喜!

论坛徽章:
0
25 [报告]
发表于 2010-07-14 10:02 |只看该作者
回复 11# c/unix


    刚才把select的过程总结了总结,给我老师汇报了一下,老师说:恩,大概就应该是这个样子。^_^,很高兴,有种从小菜鸟成长成为大菜鸟的感觉,呵呵O(∩_∩)O~   谢谢您和大家的帮助,一起分享我的喜悦吧O(∩_∩)O~

论坛徽章:
0
26 [报告]
发表于 2010-07-14 10:04 |只看该作者
回复 24# rain_fish


    O(∩_∩)O~

论坛徽章:
0
27 [报告]
发表于 2010-07-15 11:30 |只看该作者
这个应该是检测描述符是否可读可写,根据不同情况作不同的事情而已。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP