#ifndef HGL_NETWORK_IP_INCLUDE #define HGL_NETWORK_IP_INCLUDE #include #if HGL_OS == HGL_OS_Windows #include #if SOMAXCONN == 5 #error Please use #endif// typedef int socklen_t; typedef ULONG in_addr_t; #define GetLastSocketError() WSAGetLastError() #ifndef SOCK_DCCP #define SOCK_DCCP 6 #endif//SOCK_DCCP #ifndef SOCK_PACKET #define SOCK_PACKET 10 #endif//SOCK_PACKET #ifndef IPPROTO_DCCP #define IPPROTO_DCCP 33 #endif//IPPROTO_DCCP #ifndef IPPROTO_UDPLITE #define IPPROTO_UDPLITE 136 #endif//IPPROTO_UDPLITE #else #include #include #include #include #include #include #include #include #define GetLastSocketError() (errno) #if HGL_OS == HGL_OS_Linux #include inline int sendfile(int tfd,int sfd,size_t size) { return sendfile(tfd,sfd,nullptr,size); } #endif//HGL_OS == HGL_OS_Linux #if HGL_OS == HGL_OS_FreeBSD #include inline int sendfile(int tfd,int sfd,size_t size) { return sendfile(tfd,sfd,0,size,nullptr,nullptr,0); } #endif//HGL_OS == HGL_OS_FreeBSD #if (HGL_OS == HGL_OS_macOS)||(HGL_OS == HGL_OS_iOS) #ifndef IPPROTO_UDPLITE #define IPPROTO_UDPLITE 136 #endif//IPPROTO_UDPLITE #endif// #endif//HGL_OS == HGL_OS_Windows #include #include #include #include namespace hgl { namespace network { /** * IP类型枚举 */ enum IPType { iptNone=0, iptV4, iptV6, iptEnd };//enum IPType inline IPType CheckIPType(const char *name) { if(!name)return(iptNone); while(*name) { if(*name==':')return(iptV6); if(*name=='.')return(iptV4); ++name; } return(iptNone); } struct IPSupport { uint family; ///<协议家族:AF_INET,AF_INET6,AF_NETBIOS uint socktype; /// &); ///<取得本机IP支持列表 bool CheckIPSupport(const List &ips_list,uint family,uint socktype,uint protocol); bool CheckIPSupport(uint family,uint socktype,uint protocol); inline bool CheckIPv4SupportTCP (){return CheckIPSupport(AF_INET,SOCK_STREAM, IPPROTO_TCP );} inline bool CheckIPv4SupportUDP (){return CheckIPSupport(AF_INET,SOCK_DGRAM, IPPROTO_UDP );} inline bool CheckIPv4SupportUDPLite (){return CheckIPSupport(AF_INET,SOCK_DGRAM, IPPROTO_UDPLITE );} inline bool CheckIPv4SupportSCTP (){return CheckIPSupport(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP );} inline bool CheckIPv6SupportTCP (){return CheckIPSupport(AF_INET6,SOCK_STREAM, IPPROTO_TCP );} inline bool CheckIPv6SupportUDP (){return CheckIPSupport(AF_INET6,SOCK_DGRAM, IPPROTO_UDP );} inline bool CheckIPv6SupportUDPLite (){return CheckIPSupport(AF_INET6,SOCK_DGRAM, IPPROTO_UDPLITE );} inline bool CheckIPv6SupportSCTP (){return CheckIPSupport(AF_INET6,SOCK_SEQPACKET,IPPROTO_SCTP );} /** * IP地址类 */ class IPAddress { protected: int socktype; int protocol; const char *protocol_name; void RefreshProtocolName(); public: IPAddress() { socktype=0; protocol=0; protocol_name=nullptr; } IPAddress(int s,int p) { socktype=s; protocol=p; RefreshProtocolName(); } virtual ~IPAddress()=default; virtual const int GetFamily()const=0; ///<返回网络家族 const int GetSocketType()const{return socktype;} ///<返回Socket类型 const int GetProtocol()const{return protocol;} ///<返回协议类型 virtual const uint GetIPSize()const=0; ///<取得IP地址的长度 virtual const uint GetSockAddrInSize()const=0; ///<取得SockAddrIn变量长度 virtual const uint GetIPStringMaxSize()const=0; ///<取得IP字符串最大长度 virtual const bool IsBoradcast()const=0; ///<是否为广播 virtual const char *GetProtocolName()const{return protocol_name;} ///<取得协议名称 /** * 设置IP地址 * @param _name 域名或地址字符串 * @param _port 端口号 * @param socktype Socket类型(可以为SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_RDM、SOCK_SEQPACKET等值),默认为所有类型。 * @param protocol 协议类型(可以为IPPROTO_TCP、IPPROTO_UDP、IPPROTO_SCTP),默认为所有类型。 */ virtual bool Set(const char *_name,ushort _port,int socktype,int protocol)=0; bool SetTCP (const char *_name,ushort _port){return Set(_name,_port,SOCK_STREAM, IPPROTO_TCP );} bool SetUDP (const char *_name,ushort _port){return Set(_name,_port,SOCK_DGRAM, IPPROTO_UDP );} bool SetUDPLite (const char *_name,ushort _port){return Set(_name,_port,SOCK_DGRAM, IPPROTO_UDPLITE );} bool SetSCTP (const char *_name,ushort _port){return Set(_name,_port,SOCK_SEQPACKET, IPPROTO_SCTP );} const bool IsTCP ()const{if(socktype!=SOCK_STREAM )return(false);if(protocol!=IPPROTO_TCP )return(false);return(true);} const bool IsUDP ()const{if(socktype!=SOCK_DGRAM )return(false);if(protocol!=IPPROTO_UDP )return(false);return(true);} const bool IsUDPLite ()const{if(socktype!=SOCK_DGRAM )return(false);if(protocol!=IPPROTO_UDPLITE )return(false);return(true);} const bool IsSCTP ()const{if(socktype!=SOCK_SEQPACKET )return(false);if(protocol!=IPPROTO_SCTP )return(false);return(true);} /** * 设置一个仅有端口号的地址,一般用于服务器监听本机所有地址 */ virtual void Set(ushort port)=0; /** * 绑定当前IP地址到一个socket上 * @param ThisSocket Socket号 * @param reuse 是否可以复用这个IP,默认为true */ virtual bool Bind(int ThisSocket,int reuse=1)const=0; /** * 获取当前地址的主机名称 */ virtual bool GetHostname(UTF8String &)const=0; virtual sockaddr *GetSockAddr()=0; virtual void *GetIP()=0; /** * 获取当前地址的IP信息 */ virtual void GetIP(void *)=0; /** * 取得当前地址的端口号 */ virtual const ushort GetPort()const=0; /** * 转换当前地址到一个可视字符串,字符串所需长度请使用GetIPStringMaxSize()获取 */ virtual void ToString(char *,int)const=0; /** * 创建一个可视字符串地址,需自行delete[] */ virtual char *CreateString()const { const int max_size=GetIPStringMaxSize(); char *ipstr=new char[max_size+1]; ToString(ipstr,max_size); return ipstr; } /** * 创建一个当前地址的副本 */ virtual IPAddress *CreateCopy()const=0; /** * 创建一个空的IP地址副本 */ virtual IPAddress *Create()const=0; /** * 与较与另一个IP地址是否一样 */ virtual bool Comp(const IPAddress *)const=0; };//class IPAddress /** * IPv4地址 */ class IPv4Address:public IPAddress { sockaddr_in addr; public: IPv4Address(){hgl_zero(addr);} IPv4Address(const uint32 _addr,ushort port,int _socktype,int _protocol):IPAddress(_socktype,_protocol) { Set(_addr,port); } IPv4Address(const char *name,ushort port,int _socktype,int _protocol) { Set(name,port,_socktype,_protocol); } IPv4Address(ushort port,int _socktype,int _protocol) { Set(nullptr,port,_socktype,_protocol); } IPv4Address(const IPv4Address *src) { hgl_cpy(addr,src->addr); socktype=src->socktype; protocol=src->protocol; } const int GetFamily()const override{return AF_INET;} const uint GetIPSize()const override{return sizeof(in_addr);} const uint GetSockAddrInSize()const override{return sizeof(sockaddr_in);} const uint GetIPStringMaxSize()const override{return INET_ADDRSTRLEN+6;} const bool IsBoradcast()const override{return(addr.sin_addr.s_addr==htonl(INADDR_BROADCAST));} bool Set(const char *name,ushort port,int _socktype,int _protocol) override; void Set(const uint32 _addr,ushort port) { hgl_zero(addr); addr.sin_family =AF_INET; addr.sin_addr.s_addr=_addr; addr.sin_port =htons(port); } void Set(ushort port) override; bool Bind(int ThisSocket,int reuse=1)const override; bool GetHostname(UTF8String &)const override; sockaddr *GetSockAddr()override{return (sockaddr *)&addr;} void *GetIP() override {return &(addr.sin_addr);} void GetIP(void *data) override { memcpy(data,&(addr.sin_addr),sizeof(in_addr)); } const uint32 GetInt32IP()const{return addr.sin_addr.s_addr;} const ushort GetPort()const override; static void ToString(char *str,const int,const in_addr *); static void ToString(char *str,const int,const sockaddr_in *); void ToString(char *str,const int)const override; static int GetDomainIPList(List &addr_list,const char *domain,int _socktype,int _protocol); ///<取得当指定域名的IPv4地址列表 static int GetLocalIPList(List &addr_list,int _socktype,int _protocol); ///<取得本机的IPv4地址列表 IPAddress *CreateCopy()const override{return(new IPv4Address(this));} IPAddress *Create()const override{return(new IPv4Address());} bool Comp(const IPAddress *ipa)const override; };//class IPv4Address /** * IPv6地址 */ class IPv6Address:public IPAddress { sockaddr_in6 addr; public: IPv6Address(){hgl_zero(addr);} IPv6Address(const in6_addr *ip,ushort port,int _socktype,int _protocol):IPAddress(_socktype,_protocol) { hgl_zero(addr); addr.sin6_family=AF_INET6; memcpy(&(addr.sin6_addr),ip,sizeof(in6_addr)); addr.sin6_port=htons(port); } IPv6Address(const char *name,ushort port,int _socktype,int _protocol) { Set(name,port,_socktype,_protocol); } IPv6Address(ushort port,int _socktype,int _protocol) { Set(nullptr,port,_socktype,_protocol); } IPv6Address(const IPv6Address *src) { hgl_cpy(addr,src->addr); socktype=src->socktype; protocol=src->protocol; } const int GetFamily()const override{return AF_INET6;} const uint GetIPSize()const override{return sizeof(in6_addr);} const uint GetSockAddrInSize()const override{return sizeof(sockaddr_in6);} const uint GetIPStringMaxSize()const override{return INET6_ADDRSTRLEN+6;} const bool IsBoradcast()const override{return(false);} bool Set(const char *name,ushort port,int _socktype,int _protocol) override; void Set(ushort port) override; bool Bind(int ThisSocket,int reuse=1)const override; bool GetHostname(UTF8String &)const override; sockaddr *GetSockAddr() override{return (sockaddr *)&addr;} void *GetIP() override {return &(addr.sin6_addr);} void GetIP(void *data) override{memcpy(data,&(addr.sin6_addr),sizeof(in6_addr));} const ushort GetPort()const override; static void ToString(char *str,const int,const in6_addr *); static void ToString(char *str,const int,const sockaddr_in6 *); void ToString(char *str,const int)const override; static int GetDomainIPList(List &addr_list,const char *domain,int _socktype,int _protocol); ///<取得指定域名的IPv6地址列表 static int GetLocalIPList(List &addr_list,int _socktype,int _protocol); ///<取得本机的IPv6地址列表 IPAddress *CreateCopy()const override{return(new IPv6Address(this));} IPAddress *Create()const override{return(new IPv6Address());} bool Comp(const IPAddress *ipa)const override; };//class IPv6Address inline IPv4Address *CreateIPv4TCP (const char *name,ushort port){return(new IPv4Address(name,port,SOCK_STREAM, IPPROTO_TCP));} inline IPv6Address *CreateIPv6TCP (const char *name,ushort port){return(new IPv6Address(name,port,SOCK_STREAM, IPPROTO_TCP));} inline IPv4Address *CreateIPv4UDP (const char *name,ushort port){return(new IPv4Address(name,port,SOCK_DGRAM, IPPROTO_UDP));} inline IPv6Address *CreateIPv6UDP (const char *name,ushort port){return(new IPv6Address(name,port,SOCK_DGRAM, IPPROTO_UDP));} inline IPv4Address *CreateIPv4UDPLite (const char *name,ushort port){return(new IPv4Address(name,port,SOCK_DGRAM, IPPROTO_UDPLITE));} inline IPv6Address *CreateIPv6UDPLite (const char *name,ushort port){return(new IPv6Address(name,port,SOCK_DGRAM, IPPROTO_UDPLITE));} inline IPv4Address *CreateIPv4SCTP (const char *name,ushort port){return(new IPv4Address(name,port,SOCK_SEQPACKET, IPPROTO_SCTP));} inline IPv6Address *CreateIPv6SCTP (const char *name,ushort port){return(new IPv6Address(name,port,SOCK_SEQPACKET, IPPROTO_SCTP));} inline IPv4Address *CreateIPv4TCP (const uint32 &ip,ushort port){return(new IPv4Address(ip,port,SOCK_STREAM, IPPROTO_TCP));} inline IPv4Address *CreateIPv4UDP (const uint32 &ip,ushort port){return(new IPv4Address(ip,port,SOCK_DGRAM, IPPROTO_UDP));} inline IPv4Address *CreateIPv4UDPLite (const uint32 &ip,ushort port){return(new IPv4Address(ip,port,SOCK_DGRAM, IPPROTO_UDPLITE));} inline IPv4Address *CreateIPv4SCTP (const uint32 &ip,ushort port){return(new IPv4Address(ip,port,SOCK_SEQPACKET, IPPROTO_SCTP));} inline IPv6Address *CreateIPv6TCP (const in6_addr *ip,ushort port){return(new IPv6Address(ip,port,SOCK_STREAM, IPPROTO_TCP));} inline IPv6Address *CreateIPv6UDP (const in6_addr *ip,ushort port){return(new IPv6Address(ip,port,SOCK_DGRAM, IPPROTO_UDP));} inline IPv6Address *CreateIPv6UDPLite (const in6_addr *ip,ushort port){return(new IPv6Address(ip,port,SOCK_DGRAM, IPPROTO_UDPLITE));} inline IPv6Address *CreateIPv6SCTP (const in6_addr *ip,ushort port){return(new IPv6Address(ip,port,SOCK_SEQPACKET, IPPROTO_SCTP));} inline IPv4Address *CreateIPv4TCP (ushort port){return(new IPv4Address(port,SOCK_STREAM, IPPROTO_TCP));} inline IPv6Address *CreateIPv6TCP (ushort port){return(new IPv6Address(port,SOCK_STREAM, IPPROTO_TCP));} inline IPv4Address *CreateIPv4UDP (ushort port){return(new IPv4Address(port,SOCK_DGRAM, IPPROTO_UDP));} inline IPv6Address *CreateIPv6UDP (ushort port){return(new IPv6Address(port,SOCK_DGRAM, IPPROTO_UDP));} inline IPv4Address *CreateIPv4UDPLite (ushort port){return(new IPv4Address(port,SOCK_DGRAM, IPPROTO_UDPLITE));} inline IPv6Address *CreateIPv6UDPLite (ushort port){return(new IPv6Address(port,SOCK_DGRAM, IPPROTO_UDPLITE));} inline IPv4Address *CreateIPv4SCTP (ushort port){return(new IPv4Address(port,SOCK_SEQPACKET, IPPROTO_SCTP));} inline IPv6Address *CreateIPv6SCTP (ushort port){return(new IPv6Address(port,SOCK_SEQPACKET, IPPROTO_SCTP));} inline IPv4Address *CreateIPv4UDPBoradcast (ushort port){return(new IPv4Address(htonl(INADDR_BROADCAST),port,SOCK_DGRAM, IPPROTO_UDP));} inline IPv4Address *CreateIPv4UDPLiteBoradcast (ushort port){return(new IPv4Address(htonl(INADDR_BROADCAST),port,SOCK_DGRAM, IPPROTO_UDPLITE));} }//namespace network }//namespace hgl #endif//HGL_NETWORK_IP_TOOL_INCLUDE