mirror of
https://github.com/Kiritow/GSock.git
synced 2024-03-22 13:10:51 +08:00
Update GSock
Add Log. GSock will output log if compiled with GSOCK_DEBUG. Add error handling and return value reference. Fix compile error on getaddrinfo(). Fix logic error on moving sockets. Now one socket will only be opened and closed once, even if class sock is moved.
This commit is contained in:
parent
2c880cccb3
commit
5883ac5ca5
133
gsock.cpp
133
gsock.cpp
|
@ -3,12 +3,22 @@
|
||||||
* Licensed under MIT
|
* Licensed under MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Version: 2.1 */
|
/** Version: 2.2 Update: 20170815*/
|
||||||
|
|
||||||
#include "gsock.h"
|
#include "gsock.h"
|
||||||
|
|
||||||
|
#ifdef GSOCK_DEBUG
|
||||||
|
#pragma message("GSock Debug mode compiled in")
|
||||||
|
#include <cstdio>
|
||||||
|
#define myliblog(fmt,args...) printf("GSock: " fmt,##args)
|
||||||
|
#else
|
||||||
|
#define myliblog(fmt,args...)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
|
/// Using Win8.1
|
||||||
|
#define _WIN32_WINNT 0x0603
|
||||||
|
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#else
|
#else
|
||||||
|
@ -40,8 +50,12 @@ public:
|
||||||
WSAData wdt;
|
WSAData wdt;
|
||||||
wd=MAKEWORD(2,2);
|
wd=MAKEWORD(2,2);
|
||||||
int ret=WSAStartup(wd,&wdt);
|
int ret=WSAStartup(wd,&wdt);
|
||||||
|
|
||||||
|
myliblog("WSAStartup() Returns: %d\n",ret);
|
||||||
|
|
||||||
if(ret<0)
|
if(ret<0)
|
||||||
{
|
{
|
||||||
|
myliblog("WSAGetLastError: %d\n",WSAGetLastError());
|
||||||
throw std::runtime_error("Unable to load winsock2.dll. ");
|
throw std::runtime_error("Unable to load winsock2.dll. ");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -51,54 +65,96 @@ public:
|
||||||
/// Windows Platform need WinSock2.DLL clean up.
|
/// Windows Platform need WinSock2.DLL clean up.
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
|
myliblog("WSACleanup() called.");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} _init_winsock2_2_obj;
|
} _init_winsock2_2_obj;
|
||||||
|
|
||||||
|
|
||||||
class sock::_impl
|
struct sock::_impl
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
int sfd;
|
int sfd;
|
||||||
sockaddr_in saddr;
|
sockaddr_in saddr;
|
||||||
|
bool created;
|
||||||
};
|
};
|
||||||
|
|
||||||
sock::sock() : _pp(new _impl)
|
sock::sock() : _pp(new _impl)
|
||||||
{
|
{
|
||||||
_pp->sfd=socket(AF_INET,SOCK_STREAM,0);
|
myliblog("sock::sock() %p\n",this);
|
||||||
|
|
||||||
|
_pp->created=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//private
|
//private
|
||||||
sock::sock(int SocketValue) : _pp(new _impl)
|
sock::sock(int SocketValue) : _pp(new _impl)
|
||||||
{
|
{
|
||||||
|
myliblog("sock::sock(int) %p\n",this);
|
||||||
|
|
||||||
|
_pp->created=true;
|
||||||
_pp->sfd=SocketValue;
|
_pp->sfd=SocketValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sock::sock(sock&& tmp)
|
sock::sock(sock&& tmp)
|
||||||
{
|
{
|
||||||
_pp=std::move(tmp._pp);
|
myliblog("sock::sock(sock&&) %p <- %p \n",this,&tmp);
|
||||||
|
|
||||||
|
_pp=tmp._pp;
|
||||||
|
tmp._pp=nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
sock& sock::operator = (sock&& tmp)
|
sock& sock::operator = (sock&& tmp)
|
||||||
{
|
{
|
||||||
|
myliblog("sock::operator = (sock&&) %p <= %p\n",this,&tmp);
|
||||||
|
|
||||||
if(_pp)
|
if(_pp)
|
||||||
{
|
{
|
||||||
closesocket(_pp->sfd);
|
if(_pp->created)
|
||||||
|
{
|
||||||
|
myliblog("Socket closed: [%d] in %p\n",_pp->sfd,this);
|
||||||
|
closesocket(_pp->sfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete _pp;
|
||||||
}
|
}
|
||||||
_pp=std::move(tmp._pp);
|
|
||||||
|
_pp=tmp._pp;
|
||||||
|
tmp._pp=nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
sock::~sock()
|
sock::~sock()
|
||||||
{
|
{
|
||||||
|
myliblog("sock::~sock() %p\n",this);
|
||||||
|
|
||||||
if(_pp)
|
if(_pp)
|
||||||
{
|
{
|
||||||
closesocket(_pp->sfd);
|
if(_pp->created)
|
||||||
|
{
|
||||||
|
myliblog("Socket closed: [%d] in %p\n",_pp->sfd,this);
|
||||||
|
closesocket(_pp->sfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete _pp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sock::connect(const std::string& IPStr,int Port)
|
int sock::connect(const std::string& IPStr,int Port)
|
||||||
{
|
{
|
||||||
|
myliblog("sock::connect() %p\n",this);
|
||||||
|
|
||||||
|
if(_pp->created)
|
||||||
|
{
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
_pp->sfd=socket(AF_INET,SOCK_STREAM,0);
|
||||||
|
if(_pp->sfd<0)
|
||||||
|
{
|
||||||
|
myliblog("socket() returns %d. WSAGetLastError: %d\n",_pp->sfd,WSAGetLastError());
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
myliblog("Socket created: [%d] in %p\n",_pp->sfd,this);
|
||||||
|
_pp->created=true;
|
||||||
|
|
||||||
// refs
|
// refs
|
||||||
int& sfd=_pp->sfd;
|
int& sfd=_pp->sfd;
|
||||||
sockaddr_in& saddr=_pp->saddr;
|
sockaddr_in& saddr=_pp->saddr;
|
||||||
|
@ -107,6 +163,7 @@ int sock::connect(const std::string& IPStr,int Port)
|
||||||
saddr.sin_addr.s_addr=inet_addr(IPStr.c_str());
|
saddr.sin_addr.s_addr=inet_addr(IPStr.c_str());
|
||||||
saddr.sin_port=htons(Port);
|
saddr.sin_port=htons(Port);
|
||||||
saddr.sin_family=AF_INET;
|
saddr.sin_family=AF_INET;
|
||||||
|
|
||||||
return ::connect(sfd,(sockaddr*)&saddr,sizeof(saddr));
|
return ::connect(sfd,(sockaddr*)&saddr,sizeof(saddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,25 +258,53 @@ int sock::setrecvtime(int Second)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class serversock::_impl
|
struct serversock::_impl
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
int sfd;
|
int sfd;
|
||||||
sockaddr_in saddr;
|
sockaddr_in saddr;
|
||||||
|
bool created;
|
||||||
};
|
};
|
||||||
|
|
||||||
serversock::serversock() : _pp(new _impl)
|
serversock::serversock() : _pp(new _impl)
|
||||||
{
|
{
|
||||||
_pp->sfd=socket(AF_INET,SOCK_STREAM,0);
|
myliblog("serversock::serversock() %p\n",this);
|
||||||
|
|
||||||
|
_pp->created=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
serversock::~serversock()
|
serversock::~serversock()
|
||||||
{
|
{
|
||||||
closesocket(_pp->sfd);
|
myliblog("serversock::~serversock() %p\n",this);
|
||||||
|
|
||||||
|
if(_pp)
|
||||||
|
{
|
||||||
|
if(_pp->created)
|
||||||
|
{
|
||||||
|
myliblog("Server-Socket closed: [%d] in %p\n",_pp->sfd,this);
|
||||||
|
closesocket(_pp->sfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete _pp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int serversock::bind(int Port)
|
int serversock::bind(int Port)
|
||||||
{
|
{
|
||||||
|
myliblog("serversock::bind() %p\n",this);
|
||||||
|
|
||||||
|
if(_pp->created)
|
||||||
|
{
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
_pp->sfd=socket(AF_INET,SOCK_STREAM,0);
|
||||||
|
if(_pp->sfd<0)
|
||||||
|
{
|
||||||
|
myliblog("socket() returns %d. WSAGetLastError: %d\n",_pp->sfd,WSAGetLastError());
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
myliblog("Socket created: [%d] in %p\n",_pp->sfd,this);
|
||||||
|
_pp->created=true;
|
||||||
|
|
||||||
// refs
|
// refs
|
||||||
int& sfd=_pp->sfd;
|
int& sfd=_pp->sfd;
|
||||||
sockaddr_in& saddr=_pp->saddr;
|
sockaddr_in& saddr=_pp->saddr;
|
||||||
|
@ -248,24 +333,36 @@ int serversock::listen(int MaxCount)
|
||||||
return ::listen(sfd,MaxCount);
|
return ::listen(sfd,MaxCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
sock&& serversock::accept()
|
int serversock::accept(sock& _out_s)
|
||||||
{
|
{
|
||||||
|
if(_out_s._pp->created)
|
||||||
|
{
|
||||||
|
/// _out_s has been connected.
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
sock s;
|
sock s;
|
||||||
int tmp=sizeof(s._pp->saddr);
|
int tmp=sizeof(s._pp->saddr);
|
||||||
int ret=::accept(_pp->sfd,(sockaddr*)&(s._pp->saddr),&tmp);
|
int ret=::accept(_pp->sfd,(sockaddr*)&(s._pp->saddr),&tmp);
|
||||||
if(ret<0)
|
if(ret<0)
|
||||||
{
|
{
|
||||||
s._pp->sfd=-1;/// Bad Socket
|
/// accept() call failed.
|
||||||
|
myliblog("accept() returns %d. WSAGetLastError: %d\n",ret,WSAGetLastError());
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s._pp->sfd=ret;
|
s._pp->sfd=ret;
|
||||||
|
s._pp->created=true;
|
||||||
|
|
||||||
|
myliblog("Socket opened: [%d] in %p by serversock %p\n",s._pp->sfd,&s,this);
|
||||||
|
|
||||||
|
/// Move resource.
|
||||||
|
_out_s=std::move(s);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return std::move(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
@ -297,3 +394,5 @@ int DNSResolve(const std::string& HostName, std::string& _out_IPStr)
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Undefine marcos
|
||||||
|
#undef myliblog
|
||||||
|
|
35
gsock.h
35
gsock.h
|
@ -3,12 +3,12 @@
|
||||||
* Licensed under MIT
|
* Licensed under MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Version: 2.1 */
|
/** Version: 2.2 Update: 20170815*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <string>
|
||||||
|
|
||||||
class sock
|
class sock
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,11 @@ public:
|
||||||
sock& operator = (sock&&);
|
sock& operator = (sock&&);
|
||||||
~sock();
|
~sock();
|
||||||
|
|
||||||
|
/// Return:
|
||||||
|
/// 0: Connection Established. No Error.
|
||||||
|
/// -1: connect() call error. See errno.
|
||||||
|
/// -2: This socket has been connected before.
|
||||||
|
/// -3: socket() call error. Failed to create socket. See errno.
|
||||||
int connect(const std::string& IPStr,int Port);
|
int connect(const std::string& IPStr,int Port);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -28,6 +33,8 @@ public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int recv(T&);
|
int recv(T&);
|
||||||
|
|
||||||
|
/// Return:
|
||||||
|
/// return what send() and recv() call returns.
|
||||||
int send(const char* Buffer,int Length);
|
int send(const char* Buffer,int Length);
|
||||||
int recv(char* Buffer,int MaxToRecv);
|
int recv(char* Buffer,int MaxToRecv);
|
||||||
|
|
||||||
|
@ -41,8 +48,8 @@ private:
|
||||||
sock(int);
|
sock(int);
|
||||||
friend class serversock;
|
friend class serversock;
|
||||||
|
|
||||||
class _impl;
|
struct _impl;
|
||||||
std::unique_ptr<_impl> _pp;
|
_impl* _pp;
|
||||||
};
|
};
|
||||||
|
|
||||||
class serversock
|
class serversock
|
||||||
|
@ -55,14 +62,28 @@ public:
|
||||||
serversock& operator = (serversock&&) =delete;
|
serversock& operator = (serversock&&) =delete;
|
||||||
~serversock();
|
~serversock();
|
||||||
|
|
||||||
|
/// Return:
|
||||||
|
/// 0: Bind Succeed. No Error.
|
||||||
|
/// -1: bind() call error. See errno.
|
||||||
|
/// -2: This socket has been created before.
|
||||||
|
/// -3: socket() call error. Failed to create socket. See errno.
|
||||||
int bind(int Port);
|
int bind(int Port);
|
||||||
|
|
||||||
int set_reuse();
|
int set_reuse();
|
||||||
|
|
||||||
|
/// Return:
|
||||||
|
/// return what listen() call returns
|
||||||
int listen(int MaxCount);
|
int listen(int MaxCount);
|
||||||
|
|
||||||
sock&& accept();
|
/// Return:
|
||||||
|
/// 0: Accept Succeed. No Error. _out_s holds the new socket.
|
||||||
|
/// -1: accept() call error. See errno.
|
||||||
|
/// -2: _out_s is a connected socket, which should not be passed in.
|
||||||
|
int accept(sock& _out_s);
|
||||||
private:
|
private:
|
||||||
class _impl;
|
struct _impl;
|
||||||
std::unique_ptr<_impl> _pp;
|
_impl* _pp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Net Tools
|
||||||
int DNSResolve(const std::string& HostName,std::string& _out_IPStr);
|
int DNSResolve(const std::string& HostName,std::string& _out_IPStr);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user