📄 ip_address_getaddr.cpp
字号:
/* $Id: ip_address_getaddr.cpp,v 1.15 2003/09/19 10:33:02 mbn Exp $
**
** ClanLib Game SDK
** Copyright (C) 2003 The ClanLib Team
** For a total list of contributers see the file CREDITS.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
**
*/
#ifdef USE_GETADDR
#include "ip_address_getaddr.h"
#include "API/Core/System/error.h"
#include "API/Core/System/mutex.h"
#include "API/Network/Socket/socket.h"
/////////////////////////////////////////////////////////////////////////////
// CL_IPAddress construction:
CL_IPAddress_GetAddr::CL_IPAddress_GetAddr() : CL_IPAddress_Generic(), info(0)
{
// The error handling here isn't the best, ie it leaks memory
memset(&hints,0,sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
int error = getaddrinfo(NULL, "0", &hints, &info);
if(error)
throw CL_Error(gai_strerror(error));
hints.ai_socktype = SOCK_DGRAM;
addrinfo *foo;
error = getaddrinfo(NULL, "0", &hints, &foo);
if(error)
throw CL_Error(gai_strerror(error));
addrinfo *tmp = info;
while(tmp->ai_next)
{
tmp = tmp->ai_next;
}
tmp->ai_next = &foo[0];
// Both lists have to merged by use because getaddrinfo can't return both at once.
}
CL_IPAddress_GetAddr::CL_IPAddress_GetAddr(const std::string &port) :CL_IPAddress_Generic(), info(0)
{
set_port(port);
}
CL_IPAddress_GetAddr::CL_IPAddress_GetAddr(const std::string &hostname, const std::string &port) : CL_IPAddress_Generic(), info(0)
{
set_address(hostname, port);
}
CL_IPAddress_GetAddr::CL_IPAddress_GetAddr(const CL_IPAddress ©) :CL_IPAddress_Generic(), info(0)
{
set_address(copy.get_address(), copy.get_port());
}
/////////////////////////////////////////////////////////////////////////////
// CL_IPAddress attributes:
void CL_IPAddress_GetAddr::get_addrinfo(int type, sockaddr &addr, int &len, int domain) const
{
addrinfo *tmp = info;
while(tmp != NULL)
{
if(type == CL_Socket::tcp && (tmp->ai_socktype == SOCK_STREAM) && (tmp->ai_family == domain))
{
len = tmp->ai_addrlen;
memcpy(&addr, tmp->ai_addr, tmp->ai_addrlen);
return;
}
else if(type == CL_Socket::udp && (tmp->ai_socktype == SOCK_DGRAM) && (tmp->ai_family == domain))
{
len = tmp->ai_addrlen;
memcpy(&addr,tmp->ai_addr,len);
return;
}
tmp = tmp->ai_next;
}
throw CL_Error("CL_Socket: Could not find appropriate socket");
}
bool CL_IPAddress_GetAddr::operator == (const CL_IPAddress &other) const
{
if(get_address() == other.get_address() && get_port() == other.get_port())
return true;
else
return false;
}
bool CL_IPAddress_GetAddr::operator < (const CL_IPAddress &other) const
{
if(get_address() == other.get_address())
return atoi(get_port().c_str()) < atoi(other.get_port().c_str());
else
return get_address() < other.get_address();
}
bool CL_IPAddress_GetAddr::operator > (const CL_IPAddress &other) const
{
if(get_address() == other.get_address())
return atoi(get_port().c_str()) > atoi(other.get_port().c_str());
else
return get_address() > other.get_address();
}
/////////////////////////////////////////////////////////////////////////////
// CL_IPAddress operations:
void CL_IPAddress_GetAddr::set_address(const std::string &hostname, const std::string &port)
{
memset(&hints, 0, sizeof(hints));
hints.ai_flags = 0; // For now
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (info)
{
freeaddrinfo(info);
info = NULL;
}
int error = getaddrinfo(hostname.c_str(), port.c_str(), &hints, &info);
if(error)
throw CL_Error(gai_strerror(error));
addrinfo *udp;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_DGRAM;
error = getaddrinfo(hostname.c_str(), port.c_str(), &hints, &udp);
if( error )
throw CL_Error(gai_strerror(error));
addrinfo *tmp = &info[0];
while(tmp->ai_next != NULL)
{
tmp = tmp->ai_next;
}
tmp->ai_next = udp;
/*
memset(&hints, 0, sizeof(hints));
hints.ai_flags = 0; // For now
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if(info)
{
freeaddrinfo(info);
info = NULL;
}
int error = getaddrinfo(hostname.c_str(), port.c_str(), &hints, &info);
if(error)
throw CL_Error(gai_strerror(error));
*/
}
void CL_IPAddress_GetAddr::set_port(const std::string &port)
{
addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
if(info)
{
freeaddrinfo(info);
info = NULL;
}
int error = getaddrinfo(NULL, port.c_str(), &hints, &info);
if(error)
throw CL_Error(gai_strerror(error));
addrinfo *udp;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_DGRAM;
error = getaddrinfo(NULL, port.c_str(), &hints, &udp);
if( error )
throw CL_Error(gai_strerror(error));
addrinfo *tmp = &info[0];
while(tmp->ai_next != NULL)
{
tmp = tmp->ai_next;
}
tmp->ai_next = udp;
}
std::string CL_IPAddress_GetAddr::dns_lookup() const
{
char *name = new char[NI_MAXHOST];
int error = getnameinfo(info[0].ai_addr, info[0].ai_addrlen, name, NI_MAXHOST, NULL, 0, 0);
if(error)
{
delete[] name;
throw CL_Error(gai_strerror(error));
}
std::string ret(name);
delete[] name;
return ret;
}
std::string CL_IPAddress_GetAddr::get_address() const
{
char *addr = new char[NI_MAXHOST]; //Kinda ridiculous to allocate 1025 bytes for an address
memset(addr, 0, NI_MAXHOST);
int error = getnameinfo(info[0].ai_addr, info[0].ai_addrlen, addr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if(error)
{
delete[] addr;
//const char *err = gai_strerror(error);
throw CL_Error((std::string)"Error in CL_IPAddress::get_address: " + (std::string)gai_strerror(error));
}
std::string ret(addr);
delete[] addr;
return ret;
}
std::string CL_IPAddress_GetAddr::get_port() const
{
char *port = new char[NI_MAXSERV];
memset(port, 0, NI_MAXSERV);
int error = getnameinfo(info[0].ai_addr, info[0].ai_addrlen, NULL, 0, port, NI_MAXSERV, NI_NUMERICSERV);
if(error)
{
delete[] port;
throw CL_Error((std::string)"Error in CL_IPAddress::get_address: " + (std::string)gai_strerror(error));
}
std::string ret(port);
delete[] port;
return ret;
}
bool CL_IPAddress_GetAddr::is_ipv4() const
{
addrinfo *tmp = info;
while(tmp != NULL)
{
if(tmp->ai_family == PF_INET)
return true;
tmp = tmp->ai_next;
}
return false;
}
bool CL_IPAddress_GetAddr::is_ipv6() const
{
addrinfo *tmp = info;
while(tmp != NULL)
{
if(tmp->ai_family == PF_INET6)
return true;
tmp = tmp->ai_next;
}
return false;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -