This repository has been archived on 2021-11-25. You can view files and clone it, but cannot push or open issues/pull-requests.
UAPI/src/Socket.cpp

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;
}