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

📄 pipbase.cxx

📁 PTypes是一个扩充了多线程和网络功能的STL库
💻 CXX
字号:
/* * *  C++ Portable Types Library (PTypes) *  Version 2.0.2  Released 17-May-2004 * *  Copyright (C) 2001-2004 Hovik Melikyan * *  http://www.melikyan.com/ptypes/ * */#ifdef WIN32#  include <winsock2.h>#else#  include <sys/time.h>#  include <sys/types.h>#  include <sys/socket.h>#  include <netinet/in.h>#  include <arpa/inet.h>#  include <netdb.h>#  include <unistd.h>#  include <signal.h>#  include <time.h>#endif#include <stdio.h>  // for snprintf#include "pinet.h"#ifndef PTYPES_ST#  include "pasync.h"   // for mutex#endifPTYPES_BEGIN//// reentrant gehostby*() mess//#if defined(PTYPES_ST)#  define USE_GETHOSTBY#else#  if defined(WIN32)#    define USE_GETHOSTBY#  elif defined(__FreeBSD__) || defined(__DARWIN__)#    define USE_GETIPNODEBY#  elif defined(linux)#    define USE_GETHOSTBY_R6#  elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)#    define USE_LOCKED_GETHOSTBY#  else  // hopefully the Sun-style call will work on all other systems as well#    define USE_GETHOSTBY_R5#  endif#endif#define GETHOSTBY_BUF_SIZE 4096//// sockets init/startup//// usockerrno() is used in all socket classes anyway, so this module// along with the initialization code below will always be linked to// a networking program#ifdef WIN32static class _sock_init{public:    _sock_init();    ~_sock_init();} _init;_sock_init::_sock_init(){    WORD wVersionRequested;    WSADATA wsaData;    int err;    wVersionRequested = MAKEWORD(2, 0);    err = WSAStartup(wVersionRequested, &wsaData);    if ( err != 0 )        fatal(CRIT_FIRST + 50, "WinSock initialization failure");    if ( LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0 )        fatal(CRIT_FIRST + 51, "WinSock version mismatch (2.0 or compatible required)");}_sock_init::~_sock_init(){    WSACleanup();}#endif//// internet address//ipaddress ipnone = uint(0xffffffff);ipaddress ipany = INADDR_ANY;ipaddress ipbcast = INADDR_BROADCAST;ipaddress::ipaddress(int a, int b, int c, int d){    data[0] = uchar(a);    data[1] = uchar(b);    data[2] = uchar(c);    data[3] = uchar(d);}//// peer info//ippeerinfo::ippeerinfo()    : ip(ipnone), host(), port(0){}ippeerinfo::ippeerinfo(ipaddress iip, const string& ihost, int iport)    : ip(iip), host(ihost), port(iport){}ipaddress ippeerinfo::get_ip(){    if (ip == ipnone && !isempty(host))    {        ip = ulong(phostbyname(host));        if (ip == ipnone)            notfound();    }    return ip;}string ippeerinfo::get_host(){    if (!isempty(host))        return host;    if (ip == ipnone || ip == ipany || ip == ipbcast)        return nullstring;    host = phostbyaddr(ip);    if (isempty(host))        notfound();    return host;}void ippeerinfo::clear(){    ip = ipnone;    PTYPES_NAMESPACE::clear(host);    port = 0;}string ippeerinfo::asstring(bool showport) const{    string t;    if (!isempty(host))        t = host;    else if (ip == ipany)        t = '*';    else if (ip == ipnone)        t = '-';    else        t = iptostring(ip);    if (showport && port != 0)        t += ':' + itostring(port);    return t;}//// internet utilities//int ptdecl usockerrno(){#ifdef WIN32    return WSAGetLastError();#else    return errno;#endif}const char* ptdecl usockerrmsg(int code){    switch(code)    {    // only minimal set of most frequent/expressive errors; others go as "I/O error"    case ENOTSOCK:          return "Invalid socket descriptor";    case EMSGSIZE:          return "Message too long";    case ENOPROTOOPT:    case EPROTONOSUPPORT:    case EPFNOSUPPORT:    case EAFNOSUPPORT:      return "Protocol or address family not supported";    case EADDRINUSE:        return "Address already in use";    case EADDRNOTAVAIL:     return "Address not available";    case ENETDOWN:          return "Network is down";    case ENETUNREACH:       return "Network is unreachable";    case ECONNRESET:        return "Connection reset by peer";    case ETIMEDOUT:         return "Operation timed out";    case ECONNREFUSED:      return "Connection refused";    case EHOSTDOWN:         return "Host is down";    case EHOSTUNREACH:      return "No route to host";    // we always translate h_errno to ENOENT and simply show "host not found"    case ENOENT:            return "Host not found";    default: return unixerrmsg(code);    }}string ptdecl iptostring(ipaddress ip){    char buf[16];    snprintf(buf, sizeof(buf), "%d.%d.%d.%d",        uint(ip[0]), uint(ip[1]), uint(ip[2]), uint(ip[3]));    return string(buf);}#if defined(USE_LOCKED_GETHOSTBY)static mutex hplock;#endifipaddress ptdecl phostbyname(const char* name){    ipaddress ip;    hostent* hp;    if ((ip = ::inet_addr(name)) != ipnone)    {        if (ip[3] == 0) // network address?            return ipnone;    }    else    {#if defined(USE_GETHOSTBY)        if ((hp = ::gethostbyname(name)) != nil)#elif defined(USE_LOCKED_GETHOSTBY)        hplock.enter();        if ((hp = ::gethostbyname(name)) != nil)#elif defined(USE_GETIPNODEBY)        int herrno;        if ((hp = ::getipnodebyname(name, AF_INET, 0, &herrno)) != nil)#elif defined(USE_GETHOSTBY_R6)        int herrno;        hostent result;        char buf[GETHOSTBY_BUF_SIZE];        if ((::gethostbyname_r(name, &result, buf, sizeof(buf), &hp, &herrno) == 0) && hp)#elif defined(USE_GETHOSTBY_R5)        int herrno;        hostent result;        char buf[GETHOSTBY_BUF_SIZE];        if ((hp = ::gethostbyname_r(name, &result, buf, sizeof(buf), &herrno)) != nil)#endif        {            if (hp->h_addrtype == AF_INET)                memcpy(ip.data, hp->h_addr, sizeof(ip.data));#ifdef USE_GETIPNODEBY            freehostent(hp);#endif        }#if defined(USE_LOCKED_GETHOSTBY)        hplock.leave();#endif    }    return ip;}string ptdecl phostbyaddr(ipaddress ip){    hostent* hp;    string r;#if defined(USE_GETHOSTBY)    if ((hp = ::gethostbyaddr(pconst(ip.data), sizeof(ip.data), AF_INET)) != nil)#elif defined(USE_LOCKED_GETHOSTBY)    hplock.enter();    if ((hp = ::gethostbyaddr(pconst(ip.data), sizeof(ip.data), AF_INET)) != nil)#elif defined(USE_GETIPNODEBY)    int herrno;    if ((hp = ::getipnodebyaddr(pconst(ip.data), sizeof(ip.data), AF_INET, &herrno)) != nil)#elif defined(USE_GETHOSTBY_R6)    int herrno;    hostent result;    char buf[GETHOSTBY_BUF_SIZE];    if ((::gethostbyaddr_r(pconst(ip.data), sizeof(ip.data), AF_INET, &result, buf, sizeof(buf), &hp, &herrno) == 0) && hp)#elif defined(USE_GETHOSTBY_R5)    int herrno;    hostent result;    char buf[GETHOSTBY_BUF_SIZE];    if ((hp = ::gethostbyaddr_r(pconst(ip.data), sizeof(ip.data), AF_INET, &result, buf, sizeof(buf), &herrno)) != nil)#endif    {        r = hp->h_name;#ifdef USE_GETIPNODEBY        freehostent(hp);#endif    }#if defined(USE_LOCKED_GETHOSTBY)    hplock.leave();#endif    return r;}string ptdecl phostcname(const char* name){    hostent* hp;    string r;#if defined(USE_GETHOSTBY)    if ((hp = ::gethostbyname(name)) != nil)#elif defined(USE_LOCKED_GETHOSTBY)    hplock.enter();    if ((hp = ::gethostbyname(name)) != nil)#elif defined(USE_GETIPNODEBY)    int herrno;    if ((hp = ::getipnodebyname(name, AF_INET, 0, &herrno)) != nil)#elif defined(USE_GETHOSTBY_R6)    int herrno;    hostent result;    char buf[GETHOSTBY_BUF_SIZE];    if ((::gethostbyname_r(name, &result, buf, sizeof(buf), &hp, &herrno) == 0) && hp)#elif defined(USE_GETHOSTBY_R5)    int herrno;    hostent result;    char buf[GETHOSTBY_BUF_SIZE];    if ((hp = ::gethostbyname_r(name, &result, buf, sizeof(buf), &herrno)) != nil)#endif    {        r = hp->h_name;#ifdef USE_GETIPNODEBY        freehostent(hp);#endif    }#if defined(USE_LOCKED_GETHOSTBY)    hplock.leave();#endif    return r;}bool ptdecl psockwait(int handle, int timeout){#ifdef _MSC_VER// disable "condition always true" warning caused by Microsoft's FD_SET macro#  pragma warning (disable: 4127)#endif    fd_set readfds;    FD_ZERO(&readfds);    FD_SET((uint)handle, &readfds);    timeval t;    t.tv_sec = timeout / 1000;    t.tv_usec = (timeout % 1000) * 1000;    return ::select(FD_SETSIZE, &readfds, nil, nil, (timeout < 0) ? nil : &t) > 0;}bool ptdecl psockname(int handle, ippeerinfo& p){    sockaddr_in sa;    memset(&sa, 0, sizeof(sa));    psocklen addrlen = sizeof(sa);    if (getsockname(handle, (sockaddr*)&sa, &addrlen) != 0)        return false;    if (sa.sin_family != AF_INET)        return false;    p.ip = sa.sin_addr.s_addr;    p.port = ntohs(sa.sin_port);    return true;}#ifdef _MSC_VER// disable "unreachable code" warning for throw (known compiler bug)#  pragma warning (disable: 4702)#endifvoid ippeerinfo::notfound(){    string t = usockerrmsg(ENOENT);    throw new estream(nil, ENOENT, t + " [" + asstring(false) + ']');}PTYPES_END

⌨️ 快捷键说明

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