adding multiple listeners into TcpServer

This commit is contained in:
2018-06-26 14:43:43 +00:00
parent eb2755fa6b
commit d7bdc63690
7 changed files with 395 additions and 147 deletions

View File

@ -205,6 +205,30 @@ public:
/** redefines a structure of a character pointer and length */
typedef qse_mcstr_t mcstr_t;
/** defines common error codes */
enum ErrorCode
{
E_ENOERR, /**< no error */
E_EOTHER, /**< other error */
E_ENOIMPL, /**< not implemented */
E_ESYSERR, /**< subsystem error */
E_EINTERN, /**< internal error */
E_EEXCEPT, /**< exception */
E_ENOMEM,
E_EINVAL,
E_EACCES,
E_EPERM,
E_ENOENT,
E_EEXIST,
E_ENOTDIR,
E_EINTR,
E_EPIPE,
E_EINPROG, /* in progress */
E_EAGAIN /* resource unavailable unavailable */
};
};
/////////////////////////////////

View File

@ -40,27 +40,6 @@ QSE_BEGIN_NAMESPACE(QSE)
class Socket: public Uncopyable, public Types
{
public:
enum ErrorCode
{
E_ENOERR, /**< no error */
E_EOTHER, /**< other error */
E_ENOIMPL, /**< not implemented */
E_ESYSERR, /**< subsystem error */
E_EINTERN, /**< internal error */
E_ENOMEM,
E_EINVAL,
E_EACCES,
E_EPERM,
E_ENOENT,
E_EEXIST,
E_ENOTDIR,
E_EINTR,
E_EPIPE,
E_EINPROG, /* in progress */
E_EAGAIN /* resource unavailable unavailable */
};
enum Trait
{
T_NONBLOCK = (1 << 0),
@ -76,12 +55,25 @@ public:
int open (int domain, int type, int protocol, int traits = 0) QSE_CPP_NOEXCEPT;
void close () QSE_CPP_NOEXCEPT;
int shutdown (int how = 2) QSE_CPP_NOEXCEPT;
qse_sck_hnd_t getHandle() const QSE_CPP_NOEXCEPT { return this->handle; }
int getOption (int level, int optname, void* optval, qse_sck_len_t* optlen) QSE_CPP_NOEXCEPT;
int setOption (int level, int optname, const void* optval, qse_sck_len_t optlen) QSE_CPP_NOEXCEPT;
int setDebug (int n) QSE_CPP_NOEXCEPT;
int setReuseAddr (int n) QSE_CPP_NOEXCEPT;
int setReusePort (int n) QSE_CPP_NOEXCEPT;
int setKeepAlive (int n, int keepidle = 0, int keepintvl = 0, int keepcnt = 0) QSE_CPP_NOEXCEPT;
int setBroadcast (int n) QSE_CPP_NOEXCEPT;
int setSendBuf (unsigned int n) QSE_CPP_NOEXCEPT;
int setRecvBuf (unsigned int n) QSE_CPP_NOEXCEPT;
int setLingerOn (int sec) QSE_CPP_NOEXCEPT;
int setLingerOff () QSE_CPP_NOEXCEPT;
int setTcpNodelay (int n) QSE_CPP_NOEXCEPT;
int setOobInline (int n) QSE_CPP_NOEXCEPT;
int setIpv6Only (int n) QSE_CPP_NOEXCEPT;
int shutdown (int how = 2) QSE_CPP_NOEXCEPT;
int connect (const SocketAddress& target) QSE_CPP_NOEXCEPT;
int bind (const SocketAddress& target) QSE_CPP_NOEXCEPT;
int listen (int backlog = 128) QSE_CPP_NOEXCEPT;

View File

@ -37,43 +37,46 @@ QSE_BEGIN_NAMESPACE(QSE)
class SocketAddress
{
public:
SocketAddress ();
SocketAddress (int family);
SocketAddress (const qse_skad_t* skad);
SocketAddress (const qse_nwad_t* nwad);
SocketAddress () QSE_CPP_NOEXCEPT;
SocketAddress (int family) QSE_CPP_NOEXCEPT;
SocketAddress (const qse_skad_t* skad) QSE_CPP_NOEXCEPT;
SocketAddress (const qse_nwad_t* nwad) QSE_CPP_NOEXCEPT;
int getFamily () const;
int getFamily () const QSE_CPP_NOEXCEPT;
qse_skad_t* getAddrPtr()
qse_skad_t* getAddrPtr() QSE_CPP_NOEXCEPT
{
return &this->skad;
}
const qse_skad_t* getAddrPtr() const
const qse_skad_t* getAddrPtr() const QSE_CPP_NOEXCEPT
{
return &this->skad;
}
int getAddrSize () const
int getAddrSize () const QSE_CPP_NOEXCEPT
{
return qse_skadsize(&this->skad);
}
int getAddrCapa() const
int getAddrCapa() const QSE_CPP_NOEXCEPT
{
return QSE_SIZEOF(this->skad);
}
void setIpaddr (const qse_ip4ad_t* ipaddr);
void setIpaddr (const qse_ip6ad_t* ipaddr);
void setIpaddr (const qse_ip4ad_t* ipaddr) QSE_CPP_NOEXCEPT;
void setIpaddr (const qse_ip6ad_t* ipaddr) QSE_CPP_NOEXCEPT;
qse_uint16_t getPort() const; // in network-byte order
void setPort (qse_uint16_t port); // in network-byte order
qse_uint16_t getPort() const QSE_CPP_NOEXCEPT; // in network-byte order
void setPort (qse_uint16_t port) QSE_CPP_NOEXCEPT; // in network-byte order
int set (const qse_skad_t* skad) QSE_CPP_NOEXCEPT;
int set (const qse_nwad_t* nwad) QSE_CPP_NOEXCEPT;
int set (const qse_mchar_t* str) QSE_CPP_NOEXCEPT;
int set (const qse_wchar_t* str) QSE_CPP_NOEXCEPT;
int set (const qse_mchar_t* str, qse_size_t len) QSE_CPP_NOEXCEPT;
int set (const qse_wchar_t* str, qse_size_t len) QSE_CPP_NOEXCEPT;
int set (const qse_skad_t* skad);
int set (const qse_nwad_t* nwad);
int set (const qse_mchar_t* str);
int set (const qse_wchar_t* str);
protected:
qse_skad_t skad;

View File

@ -39,11 +39,11 @@ QSE_BEGIN_NAMESPACE(QSE)
// The TcpServer class implements a simple block TCP server that start a thread
// for each connection accepted.
class TcpServer: public QSE::Uncopyable
class TcpServer: public Uncopyable, public Types
{
public:
TcpServer ();
TcpServer (const SocketAddress& address);
TcpServer () QSE_CPP_NOEXCEPT;
TcpServer (const SocketAddress& address) QSE_CPP_NOEXCEPT;
virtual ~TcpServer () QSE_CPP_NOEXCEPT;
enum
@ -55,9 +55,13 @@ public:
ERR_EXCEPTION = 4
};
virtual int start (int* err_code = QSE_NULL) QSE_CPP_NOEXCEPT;
virtual int start (const qse_mchar_t* addrs) QSE_CPP_NOEXCEPT;
virtual int start (const qse_wchar_t* addrs) QSE_CPP_NOEXCEPT;
virtual int stop () QSE_CPP_NOEXCEPT;
ErrorCode getErrorCode () const QSE_CPP_NOEXCEPT { return this->errcode; }
void setErrorCode (ErrorCode errcode) QSE_CPP_NOEXCEPT { this->errcode = errcode; }
bool isServing () const QSE_CPP_NOEXCEPT
{
return this->server_serving;
@ -114,19 +118,11 @@ public:
this->thread_stack_size = tss;
}
bool getReopenSocketUponError () const QSE_CPP_NOEXCEPT
{
return this->reopen_socket_upon_error;
}
void setReopenSocketUponError (bool v) QSE_CPP_NOEXCEPT
{
this->reopen_socket_upon_error = v;
}
protected:
class Listener: public QSE::Socket
{
public:
SocketAddress address;
Listener* next_listener;
};
@ -146,15 +142,29 @@ protected:
SocketAddress address;
};
Listener* listener_head;
Listener* listener_tail;
struct ListenerList
{
ListenerList(): ep_fd(-1), head(QSE_NULL), tail(QSE_NULL), count(0)
{
this->mux_pipe[0] = -1;
this->mux_pipe[1] = -1;
}
int ep_fd;
int mux_pipe[2];
Listener* head;
Listener* tail;
qse_size_t count;
} listener;
ErrorCode errcode;
SocketAddress binding_address;
bool stop_requested;
bool server_serving;
qse_size_t max_connections;
qse_size_t thread_stack_size;
bool reopen_socket_upon_error;
typedef QSE::LinkedList<Client*> ClientList;
ClientList client_list;
@ -165,7 +175,9 @@ protected:
private:
void delete_dead_clients () QSE_CPP_NOEXCEPT;
void delete_all_clients () QSE_CPP_NOEXCEPT;
int open_tcp_socket (Socket& socket, int* err_code) QSE_CPP_NOEXCEPT;
int setup_listeners (const qse_char_t* addrs) QSE_CPP_NOEXCEPT;
void free_all_listeners () QSE_CPP_NOEXCEPT;
};