GSock/gsock.h

186 lines
4.6 KiB
C
Raw Normal View History

2017-07-27 19:52:58 +08:00
/** General Socket Wrapper
* Created By Kiritow. (https://github.com/kiritow)
* Licensed under MIT
*/
#ifndef _gsock_h
#define _gsock_h
2017-07-27 19:52:58 +08:00
#include <cstdint>
#include <string>
#include <vector>
2017-07-27 19:52:58 +08:00
2018-06-03 10:08:03 +08:00
enum
{
GSOCK_OK = 0,
GSOCK_API_ERROR = -1, // API call failed, See Errno
GSOCK_INVALID_SOCKET = -2, // Invalid socket
GSOCK_ERROR_CREAT = -3, // Socket cannot be created, See Errno
GSOCK_INVALID_IP = -4, // Invalid IP Address (IPv4,IPv6)
GSOCK_UNKNOWN_PROTOCOL = -5, // Unknown Protocol
GSOCK_ERROR_NTOP = -6, // inet_ntop failed.
GSOCK_MISMATCH_PROTOCOL = -7, // Protocol mismatch.
2018-06-03 10:08:03 +08:00
};
2018-05-05 15:37:50 +08:00
class vsock
2017-07-27 19:52:58 +08:00
{
2018-05-05 15:37:50 +08:00
protected:
vsock();
vsock(const vsock&)=delete;
vsock& operator = (const vsock&)=delete;
2018-05-09 21:30:34 +08:00
vsock(vsock&& v);
vsock& operator = (vsock&& v);
2018-05-05 15:37:50 +08:00
~vsock();
2018-05-09 21:30:34 +08:00
//vsock(int);
2018-05-05 15:37:50 +08:00
struct _impl;
_impl* _vp;
2018-05-29 13:36:38 +08:00
friend class selector;
2018-05-05 15:37:50 +08:00
};
2017-07-27 19:52:58 +08:00
2018-05-05 15:37:50 +08:00
class sock : public vsock
{
public:
/// 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.
/// -4: IP Address invalid.
2017-07-27 19:52:58 +08:00
int connect(const std::string& IPStr,int Port);
/// Return:
/// return what send() and recv() call returns.
int send(const void* Buffer,int Length);
int recv(void* Buffer, int MaxToRecv);
2017-07-27 19:52:58 +08:00
int getsendtime(int& _out_Second,int& _out_uSecond);
int getrecvtime(int& _out_Second,int& _out_uSecond);
int setsendtime(int Second);
int setrecvtime(int Second);
2018-05-04 17:44:39 +08:00
2018-05-04 18:04:29 +08:00
/// Return:
2018-06-05 13:13:06 +08:00
/// 0: Success. No Error. IPv4
/// 1: Success. No Error. IPv6
2018-05-04 18:04:29 +08:00
/// -1: getlocalname() or getpeername() call error. See errno.
/// -2: Socket not created.
2018-05-04 17:44:39 +08:00
int getlocal(std::string& IPStr,int& Port);
int getpeer(std::string& IPStr,int& Port);
2018-05-05 15:37:50 +08:00
2017-07-27 19:52:58 +08:00
friend class serversock;
private:
struct _impl;
2017-07-27 19:52:58 +08:00
};
2018-05-05 15:37:50 +08:00
class serversock : public vsock
2017-07-27 19:52:58 +08:00
{
public:
2018-06-03 10:28:04 +08:00
// use_family:
// 0: Auto (Undecided now) (default)
// 1: IPv4 (If family cannot be automatically decided, then IPv4 will be the default option)
// 2: IPv6
serversock(int use_family=0);
~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.
2017-07-27 19:52:58 +08:00
int bind(int Port);
2017-07-27 19:52:58 +08:00
int set_reuse();
/// Return:
/// return what listen() call returns
2017-07-27 19:52:58 +08:00
int listen(int MaxCount);
/// 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);
2018-05-17 19:38:40 +08:00
private:
struct _impl;
2018-06-03 10:28:04 +08:00
_impl* _pp;
2017-07-27 19:52:58 +08:00
};
2018-05-05 15:37:50 +08:00
class udpsock : public vsock
{
public:
// use_family:
// 0: Auto (Undecided now) (default)
// 1: IPv4 (If family cannot be automatically decided, then IPv4 will be the default option)
// 2: IPv6
udpsock(int use_family=0);
2018-06-03 10:28:04 +08:00
~udpsock();
2018-05-05 15:37:50 +08:00
/// Use udp socket as tcp socket. (but of course it is not).
/// connect call just copy the target socket data to kernel. See connect() for more info.
/// Return:
/// -1: connect() error.
/// -4: IP Address Invalid.
2018-05-05 15:37:50 +08:00
int connect(const std::string& IPStr,int Port);
int broadcast_at(int Port);
/// Must be called in broadcast mode.
int set_broadcast();
/// 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);
2018-05-05 15:37:50 +08:00
int broadcast(int Port,const void* buffer,int length);
/// Must call bind() before calling recvfrom().
2018-05-05 15:37:50 +08:00
int recvfrom(std::string& fromIP, int& fromPort, void* buffer, int bufferLength);
2018-05-05 15:37:50 +08:00
/// send() and recv() should only be called after connect(). Or it will fail.
int send(const void* buffer,int length);
int recv(void* buffer,int bufferLength);
private:
struct _impl;
_impl* _pp;
2018-05-05 15:37:50 +08:00
};
/// Select
class selector
{
public:
selector();
2018-05-29 13:36:38 +08:00
~selector();
2018-05-05 15:37:50 +08:00
void clear();
2018-05-29 13:36:38 +08:00
2018-05-05 15:37:50 +08:00
void add_read(const vsock&);
void add_write(const vsock&);
void add_error(const vsock&);
2018-05-29 13:36:38 +08:00
int wait_for(int second, int ms = 0);
int wait();
bool can_read(const vsock&);
bool can_write(const vsock&);
bool is_error(const vsock&);
private:
struct _impl;
_impl* _pp;
};
/// Net Tools
// Return:
// -1: getaddrinfo() call failed.
// Other: Number of fetched results from getaddrinfo() call.
int DNSResolve(const std::string& HostName, std::vector<std::string>& _out_IPStrVec);
// A wrapper of DNSResolve(...,std::vector<std::string>&)
// Return:
// -1: getaddrinfo() call failed.
// -2: Failed to resolve. (No results in vector)
// 0: Success.
2017-07-27 19:52:58 +08:00
int DNSResolve(const std::string& HostName,std::string& _out_IPStr);
2018-05-04 17:44:39 +08:00
#endif // _gsock_h