免费注册 查看新帖 |

Chinaunix

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

accept的问题,求助! [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-03-28 19:38 |只看该作者
.h

  1. #ifndef __SOCK_ACCEPTOR_H
  2. #define __SOCK_ACCEPTOR_H

  3. #include "Sock_Stream.h"
  4. #include "Net_Addr.h"
  5. #include "Sock.h"

  6. class CNF_Sock_Acceptor : public CNF_Sock
  7. {
  8. public:
  9.   enum
  10.   {
  11.     DEFAULT_BACKLOG = 3
  12.   };

  13.   bool valid();

  14.   CNF_HANDLE get_handle();

  15.   int open( const CNF_Net_Addr& addr,
  16.             bool reuse = true,
  17.             int backlog = DEFAULT_BACKLOG);

  18.   int close(void);
  19.   
  20.   // timeout_sec: >0   select
  21.   //              <=0  directly
  22.   // return:  0 successful
  23.   //         -1 failed
  24.   int accept( CNF_Sock_Stream& stream,
  25.               CNF_Net_Addr* peer = NULL,
  26.               int timeout_sec = 0);
  27. };

  28. #endif
复制代码


.cpp

  1. #include "Sock_Acceptor.h"

  2. #include <sys/select.h>
  3. #include <sys/socket.h>
  4. #include <sys/types.h>
  5. #include <sys/time.h>
  6. #include <unistd.h>
  7. #include <string.h>
  8. #include <stdio.h>

  9. #include <iostream>
  10. #include <string.h>
  11. #include <errno.h>

  12. bool CNF_Sock_Acceptor::valid()
  13. {
  14.   return INVALID_HANDLE != handle();
  15. }

  16. CNF_HANDLE CNF_Sock_Acceptor::get_handle()
  17. {
  18.   return handle();
  19. }

  20. int CNF_Sock_Acceptor::open( const CNF_Net_Addr& addr, bool reuse, int backlog)
  21. {
  22.   //check
  23.   if( valid() )
  24.     close();

  25.   //socket
  26.   int ret = socket( PF_INET, SOCK_STREAM, 0);
  27.   if( 0>ret )
  28.     return -1;

  29.   handle( ret );

  30.   set_option( MASK_REUSE_ADDR, reuse ? 1 : 0);

  31.   //bind
  32.   struct sockaddr_in sa = addr;
  33.   ret = bind( handle(), (struct sockaddr*)&sa, sizeof(sa) );
  34.   if( 0>ret )
  35.     return -1;

  36.   //listen
  37.   return listen( handle(), backlog);
  38. }

  39. int CNF_Sock_Acceptor::close(void)
  40. {
  41.   int h = handle();
  42.   return ::close( h );
  43. }

  44. int CNF_Sock_Acceptor::accept( CNF_Sock_Stream& stream,
  45.                                CNF_Net_Addr* addr,
  46.                                int timeout_sec)
  47. {
  48.   //check
  49.   if( !valid() )
  50.     return -1;

  51.   // address
  52.   struct sockaddr_in peer;
  53.   socklen_t len = sizeof(peer);

  54.   //handle
  55.   CNF_HANDLE h = handle();

  56.   //timeout
  57.   struct timeval tv;
  58.   tv.tv_sec = timeout_sec>0 ? timeout_sec : 0;
  59.   tv.tv_usec = 0;
  60.    
  61.   //select
  62.   fd_set rd;
  63.   FD_ZERO( &rd );
  64.   FD_SET( h, &rd);

  65.   while(true)
  66.   {
  67.     // 检查有效事件
  68.     FD_SET( h, &rd);
  69.     int ret = select( h+1, &rd, NULL, NULL, &tv);
  70.     if( 0>ret )
  71.     {
  72.       if( EINTR == errno )
  73.         continue; // select: 打断,继续
  74.       else
  75.       {
  76.         perror( "select failed" );
  77.         return -1;// select: 失败
  78.       }

  79.     }else if( 0 == ret)
  80.     {
  81.       std::cout<<"accept @ "<<h<<": timeout"<<std::endl;
  82.       return -1;  // select: 超时
  83.     }

  84.     // 检查有效连接
  85.     int new_handle = ::accept( h, (struct sockaddr*)&peer, &len);
  86.     std::cerr<<"accept @ "<<h<<" return "<<new_handle<<std::endl;
  87.     if( 0 > new_handle)
  88.     {
  89.       perror("accept failed");
  90.       return -1;  // accept:失败
  91.     }

  92.     if ( 0 == stream.set_handle( new_handle ) )
  93.     {
  94.       if( addr )
  95.       {
  96.         *addr = peer;
  97.       }

  98.       return 0;   // 设置:成功
  99.     }

  100.     std::cerr<<"stream.set_handle() failed"<<std::endl;
  101.     break;        // 设置: 失败
  102.   }

  103.   return -1;
  104. }
复制代码

论坛徽章:
0
12 [报告]
发表于 2007-03-28 19:58 |只看该作者
运行后程序的输出

.........

//VB 客户端第一次

process() @ 9 @ handle_input()
accept @ 9 return 10

recv @ 10 get 50 bytes

send: part1 = 33, part2 = 28

process() @ 10 @ handle_input()
recv @ 10: peer closed
process() @ 10 @ handle_close()

// VB 客户端第二次

process() @ 9 @ handle_input()
accept @ 9 return 0


send: part1 = -1, part2 = -1
send @ 0 failed: Bad file descriptor


// VC 客户端

process() @ 9 @ handle_input()
accept @ 9 return 0

process() @ 0 @ handle_input()
recv @ 0 get 101 bytes

send: part1 = 33, part2 = 0

process() @ 0 @ handle_input()
recv @ 0 get 33 bytes

process() @ 0 @ handle_input()
recv @ 0 get 33 bytes

send: part1 = 33, part2 = 896

......

论坛徽章:
0
13 [报告]
发表于 2007-03-29 11:45 |只看该作者
有人能帮我看看吗?

论坛徽章:
0
14 [报告]
发表于 2007-03-29 12:47 |只看该作者
handle 是怎么定义的?

论坛徽章:
0
15 [报告]
发表于 2007-03-29 13:08 |只看该作者
typedef int CNF_HANDLE;

CNF_HANDLE CNF_Sock::handle();

论坛徽章:
0
16 [报告]
发表于 2007-03-29 13:31 |只看该作者
原帖由 andyY 于 2007-3-29 13:08 发表
typedef int CNF_HANDLE;

CNF_HANDLE CNF_Sock::handle();

据我所知,这玩意叫声明,非定义

论坛徽章:
0
17 [报告]
发表于 2007-03-29 13:55 |只看该作者
我怎么越看那个select和accept,越感到别扭。

论坛徽章:
0
18 [报告]
发表于 2007-04-02 10:34 |只看该作者
每轮循环都应该执行FD_ZERO( &rd );

论坛徽章:
0
19 [报告]
发表于 2007-04-02 10:40 |只看该作者
原帖由 deadlylight 于 2007-4-2 10:34 发表
每轮循环都应该执行FD_ZERO( &rd );

no

论坛徽章:
0
20 [报告]
发表于 2007-04-02 11:21 |只看该作者
select返回之后应该用FD_ISSET看看是不是你想要的那个fd
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP