免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 17958 | 回复: 12
打印 上一主题 下一主题

请看我的代码!用非阻塞的accept函数要注意什么? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-07-25 20:07 |只看该作者 |倒序浏览
while(1)
        {
                //每次循环,读写集初始化
                rset = allset;
                wset = allset;
               
                //设置非阻塞I/O
                io_block_var = fcntl(tcp_fd, F_GETFL, 0);
                fcntl(tcp_fd, F_SETFL, io_block_var|O_NONBLOCK);
               
                nready = select(maxfd + 1, &rset, NULL, NULL, NULL);
                               
                //检查读集合,如果对应的TCP socket有新连接,则处理
                if (FD_ISSET(tcp_fd, &rset))
                {
                        sin_size = sizeof(struct sockaddr_in);
                        //接收新连接
                        if ((accept_fd = accept(tcp_fd, (struct sockaddr*)&remote_addr, &sin_size)) == -1)
                        {
                                printf("TCP SOCKET accept ERROR!\n");
                                continue;
                        }
                              .................
这样写accept的返回值都有哪些?应该怎么做?

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2006-07-25 20:18 |只看该作者
返回-1出错,返回非负 就是文件描述符.就可以send ,recv等操作了.

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
3 [报告]
发表于 2006-07-25 20:20 |只看该作者
不过为什么不把accept 放在while循环开始处呢?
我一般是这样做. accept放在while循环的开始处,有新来的连接 派生进程处理,如果需要响应多个描述符的时候就用非阻塞的方式.

[ 本帖最后由 mq110 于 2006-7-25 20:31 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2006-07-25 20:27 |只看该作者

回复 1楼 meijianchi 的帖子

>>
>>
>>刚看来得
>>
>>
阻塞和非阻塞
  阻塞函数在完成其指定的任务以前不允许程序调用另一个函数。例如,程序执行一个读数据的函数调用时,在此函数完成读操作以前将不会执行下一程序语句。当服务器运行到accept语句时,而没有客户连接服务请求到来,服务器就会停止在accept语句上等待连接服务请求的到来。这种情况称为阻塞(blocking)。而非阻塞操作则可以立即完成。比如,如果你希望服务器仅仅注意检查是否有客户在等待连接,有就接受连接,否则就继续做其他事情,则可以通过将Socket设置为非阻塞方式来实现。非阻塞socket在没有客户在等待时就使accept调用立即返回。
  #include
  #include
  ……
sockfd = socket(AF_INET,SOCK_STREAM,0);
fcntl(sockfd,F_SETFL,O_NONBLOCK);
……
  通过设置socket为非阻塞方式,可以实现"轮询"若干Socket。当企图从一个没有数据等待处理的非阻塞Socket读入数据时,函数将立即返回,返回值为-1,并置errno值为EWOULDBLOCK。但是这种"轮询"会使CPU处于忙等待方式,从而降低性能,浪费系统资源。而调用select()会有效地解决这个问题,它允许你把进程本身挂起来,而同时使系统内核监听所要求的一组文件描述符的任何活动,只要确认在任何被监控的文件描述符上出现活动,select()调用将返回指示该文件描述符已准备好的信息,从而实现了为进程选出随机的变化,而不必由进程本身对输入进行测试而浪费CPU开销。Select函数原型为:
int select(int numfds,fd_set *readfds,fd_set *writefds,
fd_set *exceptfds,struct timeval *timeout);
  其中readfds、writefds、exceptfds分别是被select()监视的读、写和异常处理的文件描述符集合。如果你希望确定是否可以从标准输入和某个socket描述符读取数据,你只需要将标准输入的文件描述符0和相应的sockdtfd加入到readfds集合中;numfds的值是需要检查的号码最高的文件描述符加1,这个例子中numfds的值应为sockfd+1;当select返回时,readfds将被修改,指示某个文件描述符已经准备被读取,你可以通过FD_ISSSET()来测试。为了实现fd_set中对应的文件描述符的设置、复位和测试,它提供了一组宏:
  FD_ZERO(fd_set *set)----清除一个文件描述符集;
  FD_SET(int fd,fd_set *set)----将一个文件描述符加入文件描述符集中;
  FD_CLR(int fd,fd_set *set)----将一个文件描述符从文件描述符集中清除;
  FD_ISSET(int fd,fd_set *set)----试判断是否文件描述符被置位。
  Timeout参数是一个指向struct timeval类型的指针,它可以使select()在等待timeout长时间后没有文件描述符准备好即返回。struct timeval数据结构为:
  struct timeval {
   int tv_sec; /* seconds */
   int tv_usec; /* microseconds */
};

论坛徽章:
0
5 [报告]
发表于 2006-07-25 20:41 |只看该作者
原帖由 mq110 于 2006-7-25 20:20 发表
不过为什么不把accept 放在while循环开始处呢?
我一般是这样做. accept放在while循环的开始处,有新来的连接 派生进程处理,如果需要响应多个描述符的时候就用非阻塞的方式.


我可不能用进程处理,因为我要做的是,连接很多客户端,然后客户端发数据包,根据包中的转发类型来决定是发个另一个客户端,还是所有客户端

你说的办法可行吗?您有什么好办法吗?

论坛徽章:
0
6 [报告]
发表于 2006-07-25 20:44 |只看该作者
原帖由 mq110 于 2006-7-25 20:18 发表
返回-1出错,返回非负 就是文件描述符.就可以send ,recv等操作了.


accept为-1的时候,是不是返回EWOULDBLOCK,还有什么我不知道了
这样不表明出错了吧?

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
7 [报告]
发表于 2006-07-25 20:45 |只看该作者
线程池..比较节省资源,开始的时候开线程池的话,以后就不需要为创建花费资源了,节省时间.

论坛徽章:
0
8 [报告]
发表于 2006-07-25 20:48 |只看该作者
原帖由 mq110 于 2006-7-25 20:45 发表
线程池..比较节省资源,开始的时候开线程池的话,以后就不需要为创建花费资源了,节省时间.


我是初学者,还不会用这个东西,现在要写一个这样的程序,能跑起来

想用非阻塞的accept来做,不知道要怎么处理

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
9 [报告]
发表于 2006-07-25 20:50 |只看该作者
原帖由 meijianchi 于 2006-7-25 20:44 发表


accept为-1的时候,是不是返回EWOULDBLOCK,还有什么我不知道了
这样不表明出错了吧?


这样肯定是出错了.

论坛徽章:
0
10 [报告]
发表于 2006-07-25 20:54 |只看该作者
原帖由 mq110 于 2006-7-25 20:50 发表


这样肯定是出错了.


那是不是说accpet返回-1,然后再判断error是不是EWOULDBLOCK,如果是那么不推出,就可以继续循环?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP