免费注册 查看新帖 |

Chinaunix

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

[网络] socket select 问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2012-08-03 09:53 |只看该作者
这里有一篇关于深入理解的帖子http://www.linuxgraphics.cn/gui/select_tut.html

论坛徽章:
0
12 [报告]
发表于 2012-08-03 10:14 |只看该作者
回复 10# fengfengdiandia
简明扼要。
以下是我的理解:
1,select(nfds,&fdset,(fd_set *)0,(fd_set *)0,0);  这是 server的 select
2,select(sockId+1,&selectSet,NULL,NULL,&timeOut); 这是 clinet  的select  
3,client 发给 server ,因为 server的select 没有设置超时,直接设置成了0,  server 端的select 直接返回了0,(他为什么没有阻塞在那里?而是直接返回了?)
这样就一直没有连通
4,我的做法是 让 server  先给 clinet 发数据, 这次,client 得到了数据,接着 我让client 发数据 给 server  ,这时 server 的 select 的值就是 >0,(这点怎么理解?)

   

论坛徽章:
2
2015年亚洲杯之日本
日期:2015-03-25 11:21:322015亚冠之柏太阳神
日期:2015-07-13 10:36:04
13 [报告]
发表于 2012-08-03 10:19 |只看该作者
select函数的最后一个参数若是设置为0则代表检测后就立即返回。你可以将该参数设置为 NULL,NULL代表永远等待。

因为select检测到事件发生,所以返回 >0

论坛徽章:
0
14 [报告]
发表于 2012-08-03 10:25 |只看该作者
回复 13# fengfengdiandia




"select函数的最后一个参数若是设置为0则代表检测后就立即返回。你可以将该参数设置为 NULL,NULL代表永远等待"
应该是纠结在此。
函数原型:
int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

readfds, writefds  是对读写的监听吗?我那个例子都是对读的监听, writefds  是怎么用?麻烦了  

论坛徽章:
0
15 [报告]
发表于 2012-08-03 11:09 |只看该作者
总结下:
int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
1.timeout 设置为NULL 为持续等待
2,timeout 设置为0,为立即返回
3,select 就是一个监听,检测 fdset 中的资源是否可用,将fdset  放在 readfds 是对可读的监听,同理是writefds 是对可写的监听
4.当client 对 server 持续发送数据,的设置就是
client   --  select(sockId, NULL,fdset,NULL,&timeOut);   (timeOut 设置超时时间)
server  --  select(workersock,fdset,NULL.NULL,NULL) (timeout 设置为NULL,持续等待数据)

谢谢楼上的各位帮忙,特别谢谢 @fengfengdiandia   

论坛徽章:
2
2015年亚洲杯之日本
日期:2015-03-25 11:21:322015亚冠之柏太阳神
日期:2015-07-13 10:36:04
16 [报告]
发表于 2012-08-03 11:55 |只看该作者
判断可写的情况和读其实是差不多的,我写个简单的
  1. fd_set w_set;
  2. int ret;

  3. while (1)
  4. {
  5.         FD_ZERO(&w_set);
  6.         FD_SET(sockfd, &w_set);
  7.         ret = select(sockfd + 1, NULL, &w_set, NULL, NULL);
  8.         if (ret == -1) {
  9.                 perror("select");
  10.                 exit(1);
  11.         }else if (ret == 0) {
  12.                 printf("timeout.\n");
  13.                 continue;
  14.         }
  15.         if (FD_ISSET(sockfd, &w_set)) {
  16.                 //do something
  17.                 if (sendto(sockfd, send_buf, sizeof(send_buf), 0, &sa, sizeof(sa)) == -1) { //sa代表 struct sockaddr
  18.                         perror("sendto");
  19.                         exit(1);
  20.                 }
  21.         }
  22. }
复制代码

论坛徽章:
0
17 [报告]
发表于 2012-08-03 12:36 |只看该作者
本帖最后由 fieldsplum 于 2012-08-03 12:37 编辑

首先,select的那个fd要加1;其次,没了。

论坛徽章:
0
18 [报告]
发表于 2012-08-03 13:44 |只看该作者
@liuchang8877
服务器端 初始的时候  只是用select建立对监听套接字的可读事件,
当监听套接字的可读事件做出响应时,也就是从客户端有新的连接请求,当建立好连接时,应该讲这个新的套接字也加入到select得监听事件集中,这就是select的事件循环机制
不知你做了这样的处理没有

论坛徽章:
0
19 [报告]
发表于 2012-08-03 13:46 |只看该作者
Moon_Bird 发表于 2012-08-03 13:44
@liuchang8877
服务器端 初始的时候  只是用select建立对监听套接字的可读事件,
当监听套接字的可读事件 ...

",当建立好连接时,应该讲这个新的套接字也加入到select得监听事件集中"这个好像没做, 只在之前坐了 FD_SET

论坛徽章:
0
20 [报告]
发表于 2012-08-03 13:49 |只看该作者
@liuchang8877
那估计是这个问题了, 没有对新的连接设置监听
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP