⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket.c

📁 用c++包装好的线程库,直接拿来使用,提高效率.
💻 C
字号:
//// Implemention of threaded sockets#include "threads/socket.h"#include "threads/exception.h"#if( GCC_VERSION >= 2096 )#include <sstream>#else#include <strstream>#endif#include <cstdio>#include <cerrno>extern "C" {# include <netipx/ipx.h># include <sys/stat.h># include <sys/socket.h># include <sys/un.h># include <netdb.h>};namespace cpp_threads {  typedef union {    struct sockaddr       sa;    struct sockaddr_in    in;    struct sockaddr_in6   in6;    struct sockaddr_ipx   ipx;    struct sockaddr_un    un;  } socket_types;  MessageHeader::MessageHeader()  {  }  MessageHeader::~MessageHeader()  {  }  void  MessageHeader::setName(SocketAddress* p_sa)  {    if( p_sa == 0 ) {      _Header.msg_name    = 0;      _Header.msg_namelen = 0;    } else {      _Header.msg_name    = (struct sockaddr *)*p_sa;      _Header.msg_namelen = p_sa->length();    }  }  void  MessageHeader::setControl(void *p_ca,int p_cl)  {    _Header.msg_control    = p_ca;    _Header.msg_controllen = p_cl;  }  void  MessageHeader::setFlags(int p_flags)  {    _Header.msg_flags = p_flags;  }  int  MessageHeader::getFlags()  {    return _Header.msg_flags;  }  MessageHeader&  MessageHeader::operator |= (Flags p_fl)  {    _Header.msg_flags |= p_fl;    return *this;  }  MessageHeader&  MessageHeader::operator &= (Flags p_fl)  {    _Header.msg_flags &= p_fl;    return *this;  }  MessageHeader::operator struct msghdr& ()  {    return _Header;  }  MessageHeader::operator struct msghdr* ()  {    return &_Header;  }  SocketAddress::SocketAddress(int fd_p)  {    socklen_t size;    _Sin = (struct sockaddr*)new socket_types;    getsockname(fd_p,_Sin,&size);    if( size != length() )      exception::warning("unknown protocol");  }  SocketAddress::SocketAddress(t_afamily fam_p)  {    _Sin = 0;    initFamily(fam_p);  }  SocketAddress::SocketAddress(SocketAddress& sa_p)  {    _Sin = 0;    initFamily(sa_p.family());    memcpy(_Sin,(struct sockaddr *)sa_p,length());  }  SocketAddress::~SocketAddress()  {    if( _Sin )      delete _Sin;    _Sin = 0;  }  void  SocketAddress::assign_Sin(struct sockaddr* sin_p)  {    if( _Sin )      delete _Sin;    _Sin = sin_p;  }  void  SocketAddress::initFamily(t_afamily fam_p)  {    switch( fam_p ) {    case local:      assign_Sin( (struct sockaddr*)new struct sockaddr_un );      break;    case inet:      assign_Sin( (struct sockaddr*)new struct sockaddr_in );      break;    case inet6:      assign_Sin( (struct sockaddr*)new struct sockaddr_in6 );      break;    default:      exception::fatal( "Not implemented" );    }    _Sin->sa_family = fam_p;    Pthread::debug("socket address in tree %d",fam_p);  }  SocketAddress::operator struct sockaddr *()  {    return _Sin;  }  uint  SocketAddress::length()  {    switch( _Sin->sa_family ) {    case local:      return SUN_LEN((struct sockaddr_un *)_Sin);    case inet:      return sizeof(struct sockaddr_in);    case inet6:      return sizeof(struct sockaddr_in6);    default:      return 0;    };  }  SocketAddress&  SocketAddress::operator =(SocketAddress& ref_p)  {    if( _Sin )      delete _Sin;    initFamily( ref_p.family() );    memcpy( _Sin,(struct sockaddr *)ref_p,length() );    return *this;  }  SocketAddress::t_afamily  SocketAddress::family()  {    return t_afamily(_Sin->sa_family);  }  void*  SocketAddress::host_address(const char *addr_p,t_afamily type_p)  {    struct hostent* hostinfo;    hostinfo = gethostbyname2( addr_p,type_p );    if( hostinfo == 0 )      exception::fatal( "Address unknown" );    return (void *)hostinfo->h_addr;  }  void  SocketAddress::setPort(const char *addr_p, int port_p)  {    struct sockaddr_un *sun;    struct sockaddr_in *sin;    struct sockaddr_in6 *sin6;    switch( _Sin->sa_family ) {    case local:      sun             = (struct sockaddr_un *)_Sin;      strncpy(sun->sun_path,addr_p,sizeof(sun->sun_path));      break;    case inet:      sin             = (struct sockaddr_in *)_Sin;      sin->sin_port   = htons(port_p);      sin->sin_addr   = *(struct in_addr *)host_address(addr_p,inet);      break;    case inet6:      sin6            = (struct sockaddr_in6 *)_Sin;      sin6->sin6_port = htons(port_p);      sin6->sin6_addr = *(struct in6_addr *)host_address(addr_p,inet6);      break;    default:#if( GCC_VERSION >= 2096 )      std::stringstream sstr;#else      std::strstream sstr;#endif      sstr << "Family " << _Sin->sa_family << " not implemented." << std::endl;      exception::fatal( sstr.str() );    }  }  void  SocketAddress::setPort(int port_p)    {      struct sockaddr_in *sin;      struct sockaddr_in6 *sin6;      switch( _Sin->sa_family ) {      case local:	break;      case inet:	sin                  = (struct sockaddr_in*)_Sin;	sin->sin_port        = htons(port_p);	sin->sin_addr.s_addr = htonl( INADDR_ANY );	break;      case inet6:	sin6                 = (struct sockaddr_in6*)_Sin;	sin6->sin6_port      = htons(port_p);	sin6->sin6_addr      = in6addr_any;	break;      default:	exception::fatal( "Not implemented" );      }    }  Socket::Socket()  {    _Sin             = 0;    _File_descriptor = -1;  }  Socket::Socket(int fd_p)  {    _Sin             = new SocketAddress(fd_p);    _File_descriptor = fd_p;  }  Socket::Socket(Socket& sock_p)  {    _Sin             = new SocketAddress( *(SocketAddress *)sock_p );    _File_descriptor = sock_p;  }  Socket::Socket(SocketAddress::t_afamily fam_p,__socket_type typ_p,int proto_p)  {    _File_descriptor = ::socket(fam_p,typ_p,proto_p);    if( _File_descriptor < 0 )      exception::fatal( errno );    _Sin             = new SocketAddress(fam_p);  }  void  Socket::assign_Sin(SocketAddress* sin_p)  {    if( _Sin )      delete _Sin;    _Sin = sin_p;  }  void  Socket::open(int fd_p)  {    if( !isNull() )      exception::warning( "unclosed socket" );    if( _Sin )      delete _Sin;    _File_descriptor = fd_p;    assign_Sin( new SocketAddress(fd_p) );  }  void  Socket::open(SocketAddress::t_afamily fam_p,__socket_type typ_p,int proto_p)  {    Pthread::debug("socket::open");    if( !isNull() )      exception::warning( "unclosed socket" );    _File_descriptor = ::socket(fam_p,typ_p,proto_p);    if( _File_descriptor < 0 )      exception::fatal( errno );    if( _Sin )      delete _Sin;    Pthread::debug("socket obtained %d",_File_descriptor);    assign_Sin( new SocketAddress(fam_p) );  }  void  Socket::close()  {    Pthread::debug("socket::close(%d)",_File_descriptor);    if( _File_descriptor > 0 )      ::close( _File_descriptor );    _File_descriptor = -1;  }  Socket::~Socket()  {    Pthread::debug("Socket::~Socket");    if( _Sin )      delete _Sin;  }  int  Socket::getOption(t_options opt_p)  {    socklen_t len = sizeof(int);    int value;    errno = EPERM;    if( opt_p == s_linger )      return -1;    if( getsockopt(_File_descriptor,SOL_SOCKET,opt_p,&value,&len) )      return -1;    return value;  }  bool  Socket::setOption(t_options opt_p, int val_p)  {    socklen_t len = sizeof(int);    errno = EPERM;    if( opt_p == s_linger )      return false;    if( setsockopt(_File_descriptor,SOL_SOCKET,opt_p,&val_p,len) )      return false;    return true;  }  bool  Socket::linger(bool onoff_p, int timeout_p)  {    socklen_t len = sizeof(struct linger);    struct linger l;    l.l_onoff  = onoff_p?1:0;    l.l_linger = timeout_p;    if( setsockopt(_File_descriptor,SOL_SOCKET,s_linger,&l,len) )      return false;    return true;  }  SocketAddress *  Socket::peer()  {    socklen_t len;    SocketAddress *sa;    if( isNull() )      return 0;    sa  = new SocketAddress(_Sin->family());    len = sa->length();    if( getpeername(_File_descriptor,*sa,&len) ) {      delete sa;      sa = 0;    }    return sa;  }  int  Socket::send(const char *data_p,int len_p,int flags_p)  {    int len;    _Write_lock.lock();    len = ::send(_File_descriptor,data_p,len_p,flags_p);    _Write_lock.unLock();    return len;  }  int  Socket::send(const std::string& str_p,int flags_p)  {    return send(str_p.c_str(),str_p.length(),flags_p);  }  int  Socket::sendTo(const char *data_p,int len_p,int flags_p,SocketAddress& s_p)  {    int len;    _Write_lock.lock();    len = ::sendto(_File_descriptor,data_p,len_p,flags_p,s_p,s_p.length());    _Write_lock.unLock();    return len;  }  int  Socket::sendTo(const std::string& str_p,int flags_p,SocketAddress& s_p)  {    return sendTo(str_p.c_str(),str_p.length(),flags_p,s_p);  }  int  Socket::sendMsg(MessageHeader& mh_p,int flags_p)  {    int len;    _Write_lock.lock();    len = ::sendmsg(_File_descriptor,mh_p,flags_p);    _Write_lock.lock();    return len;  }  int  Socket::recv(void *buf_p,int len_p,uint flags_p)  {    int len;    _Read_lock.lock();    len = ::recv(_File_descriptor,buf_p,len_p,flags_p);    _Read_lock.unLock();    return len;  }  int  Socket::recvFrom(void *buf_p,int len_p,uint flags_p,SocketAddress& s_p)  {    int len;    socklen_t slen;    _Read_lock.lock();    len = ::recvfrom(_File_descriptor,buf_p,len_p,flags_p,s_p,&slen);    _Read_lock.unLock();    // Does not need to be fatal, but requires an interception.    if( slen != s_p.length() )      exception::warning("unknown protocol type");    return len;  }  int  Socket::recvMsg(MessageHeader& mh_p,int flags_p)  {    int len;    _Read_lock.lock();    len = ::recvmsg(_File_descriptor,mh_p,flags_p);    _Read_lock.unLock();    return len;  }  int    Socket::read(const char *data_p,int len_p)    {      int len;            verifySocket();      _Read_lock.lock();      len = ::read(_File_descriptor,(void *)data_p,len_p);      _Read_lock.unLock();      return len;    }  int    Socket::write(const char *data_p,int len_p)    {      int len;      Pthread::debug("write(%d,'%s',%d)",_File_descriptor,data_p,len_p);      verifySocket();      _Write_lock.lock();      len = ::write(_File_descriptor,data_p,len_p);      _Write_lock.unLock();      return len;    }  int  Socket::write(const std::string& str_p)  {    return write(str_p.c_str(),str_p.length());  }  void    Socket::connect(const char *name_p, int port_p)    {      verifySocket();      _Sin->setPort( name_p,port_p );      if( ::connect(_File_descriptor,*_Sin,_Sin->length()) == -1 )	exception::fatal( errno );    }  void    Socket::bind(int port_p)    {      verifySocket();      _Sin->setPort( port_p );      if( ::bind(_File_descriptor,*_Sin,_Sin->length()) == -1 )	exception::fatal( errno );    }  void    Socket::listen(int queue_p)    {      verifySocket();      if( ::listen(_File_descriptor,queue_p) == -1 )	exception::fatal( errno );    }  Socket*  Socket::accept()  {    struct sockaddr_in  clientname;    struct sockaddr_in6 client6name;    socklen_t           size;    int                 fd = 0;    verifySocket();    switch( _Sin->family() ) {    case SocketAddress::inet:      size = sizeof(clientname);      fd   = ::accept(_File_descriptor,(struct sockaddr*)&clientname,&size);      break;    case SocketAddress::inet6:      size = sizeof(client6name);      fd   = ::accept(_File_descriptor,(struct sockaddr*)&client6name,&size);      break;    default:      exception::fatal( "Not implemented" );    }    return (new Socket(fd));  }  void  Socket::verifySocket()  {    if( !isNull() )      return;    exception::fatal( "Operation on null socket" );  }  bool  Socket::isNull()  {    if( _Sin == 0 || _File_descriptor < 0 )      return true;    return false;  }  Socket::operator int()  {    return _File_descriptor;  }  Socket::operator SocketAddress *()  {    return _Sin;  }  Socket&  Socket::operator =(Socket& ref_p)  {    assign_Sin( new SocketAddress(*(SocketAddress *)ref_p) );    _File_descriptor = ref_p;    return *this;  }  bool  Socket::operator ==(Socket& ref_p)  {    return _File_descriptor == (int)ref_p;  }  Socket::operator bool()  {    struct stat sbuf;    if( fstat( _File_descriptor,&sbuf ) )      return false;    if( !S_ISSOCK(sbuf.st_mode) )      return false;    return true;  }};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -