130 lines
2.5 KiB
C++
130 lines
2.5 KiB
C++
#include "util.h"
|
|
#include "util_include.h"
|
|
|
|
/// The following code is part of General Socket Wrapper (GSock) Project
|
|
/// Under MIT License
|
|
#define _WIN32_WINNT 0x0603
|
|
#include <windows.h>
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
|
|
#include <string>
|
|
#include <stdexcept>
|
|
|
|
class _init_winsock2_2_class
|
|
{
|
|
public:
|
|
_init_winsock2_2_class()
|
|
{
|
|
/// Windows Platform need WinSock2.DLL initialization.
|
|
WORD wd;
|
|
WSAData wdt;
|
|
wd=MAKEWORD(2,2);
|
|
if(WSAStartup(wd,&wdt)<0)
|
|
{
|
|
throw std::runtime_error("Unable to load winsock2.dll. ");
|
|
}
|
|
}
|
|
~_init_winsock2_2_class()
|
|
{
|
|
/// Windows Platform need WinSock2.DLL clean up.
|
|
WSACleanup();
|
|
}
|
|
};
|
|
|
|
static _init_winsock2_2_class _init_winsock2_2_obj;
|
|
|
|
class Socket::_impl
|
|
{
|
|
public:
|
|
int sfd;
|
|
sockaddr_in saddr;
|
|
bool created;
|
|
};
|
|
|
|
Socket::Socket() : _pp(new _impl)
|
|
{
|
|
_pp->created=false;
|
|
}
|
|
|
|
Socket::~Socket()
|
|
{
|
|
if(_pp)
|
|
{
|
|
if(_pp->created)
|
|
{
|
|
closesocket(_pp->sfd);
|
|
}
|
|
|
|
delete _pp;
|
|
}
|
|
}
|
|
|
|
int Socket::connect(const std::string& IPStr,int Port)
|
|
{
|
|
if(_pp->created)
|
|
{
|
|
return -2;
|
|
}
|
|
_pp->sfd=socket(AF_INET,SOCK_STREAM,0);
|
|
if(_pp->sfd<0)
|
|
{
|
|
return -3;
|
|
}
|
|
_pp->created=true;
|
|
|
|
// refs
|
|
int& sfd=_pp->sfd;
|
|
sockaddr_in& saddr=_pp->saddr;
|
|
|
|
memset(&saddr,0,sizeof(saddr));
|
|
saddr.sin_addr.s_addr=inet_addr(IPStr.c_str());
|
|
saddr.sin_port=htons(Port);
|
|
saddr.sin_family=AF_INET;
|
|
|
|
return ::connect(sfd,(sockaddr*)&saddr,sizeof(saddr));
|
|
}
|
|
|
|
int Socket::send(const void* Buffer,int Length)
|
|
{
|
|
return ::send(_pp->sfd,(const char*)Buffer,Length,0);
|
|
}
|
|
|
|
int Socket::recv(void* Buffer,int MaxToRecv)
|
|
{
|
|
return ::recv(_pp->sfd,(char*)Buffer,MaxToRecv,0);
|
|
}
|
|
|
|
int DNSResolve(const std::string& HostName, std::string& _out_IPStr)
|
|
{
|
|
/// Use getaddrinfo instead
|
|
struct addrinfo hints;
|
|
memset(&hints,0,sizeof(hints));
|
|
hints.ai_family=AF_UNSPEC;
|
|
hints.ai_socktype=SOCK_STREAM;
|
|
hints.ai_protocol=IPPROTO_TCP;
|
|
|
|
struct addrinfo* result=nullptr;
|
|
|
|
int ret=getaddrinfo(HostName.c_str(),NULL,&hints,&result);
|
|
if(ret!=0)
|
|
{
|
|
return -1;/// API Call Failed.
|
|
}
|
|
for(struct addrinfo* ptr=result; ptr!=nullptr; ptr=ptr->ai_next)
|
|
{
|
|
switch(ptr->ai_family)
|
|
{
|
|
case AF_INET:
|
|
sockaddr_in* addr=(struct sockaddr_in*) (ptr->ai_addr) ;
|
|
_out_IPStr=inet_ntoa(addr->sin_addr);
|
|
return 0;
|
|
break;
|
|
}
|
|
}
|
|
/// Unknown error.
|
|
return -2;
|
|
}
|
|
|
|
|