📄 pipbase.cxx
字号:
/* * * C++ Portable Types Library (PTypes) * Version 1.7.5 Released 9-Mar-2003 * * Copyright (c) 2001, 2002, 2003 Hovik Melikyan * * http://www.melikyan.com/ptypes/ * http://ptypes.sourceforge.net/ * */#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 "pasync.h"#include "pinet.h"PTYPES_BEGIN//// 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;}void ippeerinfo::notfound(){ string t = usockerrmsg(ENOENT); throw new estream(nil, ENOENT, t + " [" + asstring(false) + ']');}//// internet utilities//int usockerrno(){#ifdef WIN32 return WSAGetLastError();#else return errno;#endif}const char* 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 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);}ipaddress phostbyname(const char* name){ ipaddress ip; hostent* hp; if ((ip = ::inet_addr(name)) != ipnone) { if (ip[3] == 0) // network address? return ipnone; } else { if ((hp = ::gethostbyname(name)) == nil) return ipnone; if (hp->h_addrtype != AF_INET) return ipnone; memcpy(ip.data, hp->h_addr, sizeof(ip.data)) ; } return ip;}string phostbyaddr(ipaddress ip){ hostent* hp; string r; if ((hp = ::gethostbyaddr(pconst(ip.data), sizeof(ip.data), AF_INET)) != nil) r = hp->h_name; return r;}string phostcname(const char* name){ hostent* hp; string r; if ((hp = ::gethostbyname(name)) != nil) r = hp->h_name; return r;}bool 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 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 = sa.sin_port; return true;}PTYPES_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -