- 论坛徽章:
- 0
|
.h
- #ifndef __SOCK_ACCEPTOR_H
- #define __SOCK_ACCEPTOR_H
- #include "Sock_Stream.h"
- #include "Net_Addr.h"
- #include "Sock.h"
- class CNF_Sock_Acceptor : public CNF_Sock
- {
- public:
- enum
- {
- DEFAULT_BACKLOG = 3
- };
- bool valid();
- CNF_HANDLE get_handle();
- int open( const CNF_Net_Addr& addr,
- bool reuse = true,
- int backlog = DEFAULT_BACKLOG);
- int close(void);
-
- // timeout_sec: >0 select
- // <=0 directly
- // return: 0 successful
- // -1 failed
- int accept( CNF_Sock_Stream& stream,
- CNF_Net_Addr* peer = NULL,
- int timeout_sec = 0);
- };
- #endif
复制代码
.cpp
- #include "Sock_Acceptor.h"
- #include <sys/select.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdio.h>
- #include <iostream>
- #include <string.h>
- #include <errno.h>
- bool CNF_Sock_Acceptor::valid()
- {
- return INVALID_HANDLE != handle();
- }
- CNF_HANDLE CNF_Sock_Acceptor::get_handle()
- {
- return handle();
- }
- int CNF_Sock_Acceptor::open( const CNF_Net_Addr& addr, bool reuse, int backlog)
- {
- //check
- if( valid() )
- close();
- //socket
- int ret = socket( PF_INET, SOCK_STREAM, 0);
- if( 0>ret )
- return -1;
- handle( ret );
- set_option( MASK_REUSE_ADDR, reuse ? 1 : 0);
- //bind
- struct sockaddr_in sa = addr;
- ret = bind( handle(), (struct sockaddr*)&sa, sizeof(sa) );
- if( 0>ret )
- return -1;
- //listen
- return listen( handle(), backlog);
- }
- int CNF_Sock_Acceptor::close(void)
- {
- int h = handle();
- return ::close( h );
- }
- int CNF_Sock_Acceptor::accept( CNF_Sock_Stream& stream,
- CNF_Net_Addr* addr,
- int timeout_sec)
- {
- //check
- if( !valid() )
- return -1;
- // address
- struct sockaddr_in peer;
- socklen_t len = sizeof(peer);
- //handle
- CNF_HANDLE h = handle();
- //timeout
- struct timeval tv;
- tv.tv_sec = timeout_sec>0 ? timeout_sec : 0;
- tv.tv_usec = 0;
-
- //select
- fd_set rd;
- FD_ZERO( &rd );
- FD_SET( h, &rd);
- while(true)
- {
- // 检查有效事件
- FD_SET( h, &rd);
- int ret = select( h+1, &rd, NULL, NULL, &tv);
- if( 0>ret )
- {
- if( EINTR == errno )
- continue; // select: 打断,继续
- else
- {
- perror( "select failed" );
- return -1;// select: 失败
- }
- }else if( 0 == ret)
- {
- std::cout<<"accept @ "<<h<<": timeout"<<std::endl;
- return -1; // select: 超时
- }
- // 检查有效连接
- int new_handle = ::accept( h, (struct sockaddr*)&peer, &len);
- std::cerr<<"accept @ "<<h<<" return "<<new_handle<<std::endl;
- if( 0 > new_handle)
- {
- perror("accept failed");
- return -1; // accept:失败
- }
- if ( 0 == stream.set_handle( new_handle ) )
- {
- if( addr )
- {
- *addr = peer;
- }
- return 0; // 设置:成功
- }
- std::cerr<<"stream.set_handle() failed"<<std::endl;
- break; // 设置: 失败
- }
- return -1;
- }
复制代码 |
|