Update to 2.3.4

Add UDP support.
Change to standard marco.
This commit is contained in:
Kirigaya Kazuto 2018-04-23 15:56:05 +08:00
parent b8fc3e310a
commit 5a32be1e79
3 changed files with 146 additions and 38 deletions

1
VERSION Normal file
View File

@ -0,0 +1 @@
2.3.4

155
gsock.cpp
View File

@ -3,19 +3,19 @@
* Licensed under MIT * Licensed under MIT
*/ */
/** Version: 2.2 Update: 20170815*/ /** See VERSION for version information */
#include "gsock.h" #include "gsock.h"
#ifdef GSOCK_DEBUG #ifdef GSOCK_DEBUG
#pragma message("GSock Debug mode compiled in") #pragma message("GSock Debug mode compiled in")
#include <cstdio> #include <cstdio>
#define myliblog(fmt,args...) printf("GSock: " fmt,##args) #define myliblog(fmt,...) printf("GSock: " fmt,__VA_ARGS__)
#else #else
#define myliblog(fmt,args...) #define myliblog(fmt,...)
#endif #endif
#ifdef __WIN32__ #ifdef _WIN32
/// Using Win8.1 /// Using Win8.1
#define _WIN32_WINNT 0x0603 #define _WIN32_WINNT 0x0603
@ -46,7 +46,7 @@ public:
_init_winsock2_2_class() _init_winsock2_2_class()
{ {
/// Windows Platform need WinSock2.DLL initialization. /// Windows Platform need WinSock2.DLL initialization.
#ifdef __WIN32__ #ifdef _WIN32
WORD wd; WORD wd;
WSAData wdt; WSAData wdt;
wd=MAKEWORD(2,2); wd=MAKEWORD(2,2);
@ -64,7 +64,7 @@ public:
~_init_winsock2_2_class() ~_init_winsock2_2_class()
{ {
/// Windows Platform need WinSock2.DLL clean up. /// Windows Platform need WinSock2.DLL clean up.
#ifdef __WIN32__ #ifdef _WIN32
WSACleanup(); WSACleanup();
myliblog("WSACleanup() called."); myliblog("WSACleanup() called.");
#endif #endif
@ -81,7 +81,7 @@ struct sock::_impl
sock::sock() : _pp(new _impl) sock::sock() : _pp(new _impl)
{ {
myliblog("sock::sock() %p\n",this); myliblog("sock::sock() %p", this);
_pp->created=false; _pp->created=false;
} }
@ -188,7 +188,7 @@ int sock::getsendtime(int& _out_Second, int& _out_uSecond)
int ret=getsockopt(sfd,SOL_SOCKET,SO_SNDTIMEO,(char*)&outtime,&_not_used_t); int ret=getsockopt(sfd,SOL_SOCKET,SO_SNDTIMEO,(char*)&outtime,&_not_used_t);
if(ret<0) return ret; if(ret<0) return ret;
/// We don't know why, but on Windows, 1 Second means 1000. /// We don't know why, but on Windows, 1 Second means 1000.
#ifdef __WIN32__ #ifdef _WIN32
_out_Second=outtime.tv_sec/1000; _out_Second=outtime.tv_sec/1000;
_out_uSecond=outtime.tv_usec; _out_uSecond=outtime.tv_usec;
#else #else
@ -209,7 +209,7 @@ int sock::getrecvtime(int& _out_Second, int& _out_uSecond)
int ret=getsockopt(sfd,SOL_SOCKET,SO_RCVTIMEO,(char*)&outtime,&_not_used_t); int ret=getsockopt(sfd,SOL_SOCKET,SO_RCVTIMEO,(char*)&outtime,&_not_used_t);
if(ret<0) return ret; if(ret<0) return ret;
/// We don't know why, but on Windows, 1 Second means 1000. /// We don't know why, but on Windows, 1 Second means 1000.
#ifdef __WIN32__ #ifdef _WIN32
_out_Second=outtime.tv_sec/1000; _out_Second=outtime.tv_sec/1000;
_out_uSecond=outtime.tv_usec; _out_uSecond=outtime.tv_usec;
#else #else
@ -227,7 +227,7 @@ int sock::setsendtime(int Second)
struct timeval outtime; struct timeval outtime;
/// We don't know why, but on Windows, 1 Second means 1000. /// We don't know why, but on Windows, 1 Second means 1000.
#ifdef __WIN32__ #ifdef _WIN32
outtime.tv_sec=Second*1000; outtime.tv_sec=Second*1000;
outtime.tv_usec=0; outtime.tv_usec=0;
#else #else
@ -245,7 +245,7 @@ int sock::setrecvtime(int Second)
struct timeval outtime; struct timeval outtime;
/// We don't know why, but on Windows, 1 Second means 1000. /// We don't know why, but on Windows, 1 Second means 1000.
#ifdef __WIN32__ #ifdef _WIN32
outtime.tv_sec=Second*1000; outtime.tv_sec=Second*1000;
outtime.tv_usec=0; outtime.tv_usec=0;
#else #else
@ -364,36 +364,119 @@ int serversock::accept(sock& _out_s)
} }
} }
struct udpsock::_impl
{
int sfd;
int lastErr;
};
udpsock::udpsock() : _pp(new _impl)
{
_pp->sfd = socket(AF_INET, SOCK_DGRAM, 0);
_pp->lastErr = 0;
}
udpsock::udpsock(udpsock&& x)
{
_pp = x._pp;
x._pp = nullptr;
}
udpsock& udpsock::operator=(udpsock&& x)
{
if (_pp)
{
// Clean up itself.
this->~udpsock();
}
_pp = x._pp;
x._pp = nullptr;
return *this;
}
udpsock::~udpsock()
{
closesocket(_pp->sfd);
delete _pp;
}
int udpsock::bind(int Port)
{
sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(Port);
saddr.sin_addr.s_addr = INADDR_ANY;
return ::bind(_pp->sfd, (const sockaddr*)&saddr, sizeof(saddr));
}
int udpsock::sendto(const std::string& IPStr, int Port, const void* buffer, int length)
{
sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(Port);
saddr.sin_addr.s_addr = inet_addr(IPStr.c_str());
return ::sendto(_pp->sfd, (const char*)buffer, length, 0, (const sockaddr*)&saddr, sizeof(saddr));
}
int udpsock::recvfrom(std::string& fromIP, void* buffer, int bufferLength)
{
sockaddr_in saddr;
int saddrlen = sizeof(saddr);
int ret = ::recvfrom(_pp->sfd, (char*)buffer, bufferLength, 0, (sockaddr*)&saddr, &saddrlen);
if (ret < 0)
{
#ifdef _WIN32
_pp->lastErr = WSAGetLastError();
#else
_pp->lastErr = errno;
#endif
}
fromIP = inet_ntoa(saddr.sin_addr);
return ret;
}
int udpsock::getlasterror()
{
return _pp->lastErr;
}
int DNSResolve(const std::string& HostName, std::string& _out_IPStr) int DNSResolve(const std::string& HostName, std::string& _out_IPStr)
{ {
/// Use getaddrinfo instead /// Use getaddrinfo instead
struct addrinfo hints; struct addrinfo hints;
memset(&hints,0,sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family=AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype=SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol=IPPROTO_TCP; hints.ai_protocol = IPPROTO_TCP;
struct addrinfo* result=nullptr; struct addrinfo* result = nullptr;
int ret=getaddrinfo(HostName.c_str(),NULL,&hints,&result); int ret = getaddrinfo(HostName.c_str(), NULL, &hints, &result);
if(ret!=0) if (ret != 0)
{ {
return -1;/// API Call Failed. return -1;/// API Call Failed.
} }
for(struct addrinfo* ptr=result; ptr!=nullptr; ptr=ptr->ai_next) for (struct addrinfo* ptr = result; ptr != nullptr; ptr = ptr->ai_next)
{ {
switch(ptr->ai_family) switch (ptr->ai_family)
{ {
case AF_INET: case AF_INET:
sockaddr_in* addr=(struct sockaddr_in*) (ptr->ai_addr) ; sockaddr_in * addr = (struct sockaddr_in*) (ptr->ai_addr);
_out_IPStr=inet_ntoa(addr->sin_addr); _out_IPStr = inet_ntoa(addr->sin_addr);
return 0; return 0;
break; break;
} }
} }
/// Unknown error. /// Unknown error.
return -2; return -2;
} }
/// Undefine marcos /// Undefine marcos
#undef myliblog #undef myliblog

28
gsock.h
View File

@ -12,7 +12,7 @@
class sock class sock
{ {
public: public:
sock(); sock();
sock(const sock&)=delete; sock(const sock&)=delete;
sock& operator = (const sock&)=delete; sock& operator = (const sock&)=delete;
sock(sock&&); sock(sock&&);
@ -35,7 +35,7 @@ public:
/// Return: /// Return:
/// return what send() and recv() call returns. /// return what send() and recv() call returns.
int send(const void* Buffer,int Length); int send(const void* Buffer,int Length);
int recv(void* Buffer,int MaxToRecv); int recv(void* Buffer, int MaxToRecv);
int getsendtime(int& _out_Second,int& _out_uSecond); int getsendtime(int& _out_Second,int& _out_uSecond);
int getrecvtime(int& _out_Second,int& _out_uSecond); int getrecvtime(int& _out_Second,int& _out_uSecond);
@ -84,6 +84,30 @@ private:
_impl* _pp; _impl* _pp;
}; };
class udpsock
{
public:
udpsock();
udpsock(const udpsock&) = delete;
udpsock& operator = (const udpsock&) = delete;
udpsock(udpsock&&);
udpsock& operator = (udpsock&&);
~udpsock();
/// Explict bind() call is only need when you have to receive data.
int bind(int Port);
int sendto(const std::string& IPStr, int Port, const void* buffer, int length);
/// Must call bind() before calling recvfrom().
int recvfrom(std::string& fromIP, void* buffer, int bufferLength);
int getlasterror();
private:
struct _impl;
_impl* _pp;
};
/// Net Tools /// Net Tools
int DNSResolve(const std::string& HostName,std::string& _out_IPStr); int DNSResolve(const std::string& HostName,std::string& _out_IPStr);