work in progress. adding TcpServer
This commit is contained in:
@ -341,16 +341,16 @@
|
||||
#else
|
||||
|
||||
# define QSE_ASSERT(expr) (void)((expr) || \
|
||||
(qse_assert_failed (QSE_T(#expr), QSE_NULL, QSE_T(__FILE__), __LINE__), 0))
|
||||
(QSE_ASSERT_failed (QSE_T(#expr), QSE_NULL, QSE_T(__FILE__), __LINE__), 0))
|
||||
# define QSE_ASSERTX(expr,desc) (void)((expr) || \
|
||||
(qse_assert_failed (QSE_T(#expr), QSE_T(desc), QSE_T(__FILE__), __LINE__), 0))
|
||||
(QSE_ASSERT_failed (QSE_T(#expr), QSE_T(desc), QSE_T(__FILE__), __LINE__), 0))
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
QSE_EXPORT void qse_assert_failed (
|
||||
QSE_EXPORT void QSE_ASSERT_failed (
|
||||
const qse_char_t* expr, const qse_char_t* desc,
|
||||
const qse_char_t* file, qse_size_t line);
|
||||
#if defined(__cplusplus)
|
||||
|
@ -32,6 +32,7 @@ pkginclude_HEADERS += \
|
||||
SocketAddress.hpp \
|
||||
Socket.hpp \
|
||||
SpinLock.hpp \
|
||||
TcpServer.hpp \
|
||||
Thread.hpp
|
||||
endif
|
||||
|
||||
|
@ -92,6 +92,7 @@ host_triplet = @host@
|
||||
@ENABLE_CXX_TRUE@ SocketAddress.hpp \
|
||||
@ENABLE_CXX_TRUE@ Socket.hpp \
|
||||
@ENABLE_CXX_TRUE@ SpinLock.hpp \
|
||||
@ENABLE_CXX_TRUE@ TcpServer.hpp \
|
||||
@ENABLE_CXX_TRUE@ Thread.hpp
|
||||
|
||||
subdir = include/qse/si
|
||||
@ -135,7 +136,7 @@ am__pkginclude_HEADERS_DIST = aio.h aio-pro.h aio-sck.h cnd.h dir.h \
|
||||
fio.h fs.h glob.h intr.h log.h mtx.h mux.h nwad.h nwif.h \
|
||||
nwio.h pio.h rwl.h sck.h sinfo.h sio.h spl.h task.h thr.h \
|
||||
tio.h AppRoot.hpp SocketAddress.hpp Socket.hpp SpinLock.hpp \
|
||||
Thread.hpp
|
||||
TcpServer.hpp Thread.hpp
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
@ -357,7 +358,6 @@ pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
runstatedir = @runstatedir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
|
@ -76,9 +76,15 @@ 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;
|
||||
|
||||
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 connect (const SocketAddress& target) QSE_CPP_NOEXCEPT;
|
||||
int bind (const SocketAddress& target) QSE_CPP_NOEXCEPT;
|
||||
int listen (int backlog) QSE_CPP_NOEXCEPT;
|
||||
int listen (int backlog = 128) QSE_CPP_NOEXCEPT;
|
||||
int accept (Socket* newsck, SocketAddress* newaddr, int traits = 0) QSE_CPP_NOEXCEPT;
|
||||
|
||||
// The send() functions sends data by attemping a single call to the
|
||||
@ -96,6 +102,7 @@ public:
|
||||
qse_ssize_t receive (void* buf, qse_size_t len, SocketAddress& srcaddr) QSE_CPP_NOEXCEPT;
|
||||
|
||||
/* TODO: sendmsg, recvmsg */
|
||||
|
||||
protected:
|
||||
qse_sck_hnd_t handle;
|
||||
ErrorCode errcode;
|
||||
|
164
qse/include/qse/si/TcpServer.hpp
Normal file
164
qse/include/qse/si/TcpServer.hpp
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EQSERESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _QSE_SI_TCPSERVER_CLASS_
|
||||
#define _QSE_SI_TCPSERVER_CLASS_
|
||||
|
||||
#include <qse/si/Socket.hpp>
|
||||
#include <qse/si/SocketAddress.hpp>
|
||||
#include <qse/si/Thread.hpp>
|
||||
#include <qse/cmn/LinkedList.hpp>
|
||||
#include <qse/Uncopyable.hpp>
|
||||
|
||||
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
|
||||
class TcpServer: public QSE::Uncopyable
|
||||
{
|
||||
public:
|
||||
TcpServer ();
|
||||
TcpServer (const SocketAddress& address);
|
||||
virtual ~TcpServer ();
|
||||
|
||||
enum
|
||||
{
|
||||
ERR_NONE = 0,
|
||||
ERR_OPEN = 1,
|
||||
ERR_BIND = 2,
|
||||
ERR_LISTEN = 3,
|
||||
ERR_EXCEPTION = 4
|
||||
};
|
||||
|
||||
virtual int start (int* err_code = QSE_NULL);
|
||||
virtual int start (bool winsock_inheritable, int* err_code = QSE_NULL);
|
||||
virtual int stop ();
|
||||
|
||||
bool isServing () const
|
||||
{
|
||||
return this->server_serving;
|
||||
}
|
||||
|
||||
bool isStopRequested () const
|
||||
{
|
||||
return this->stop_requested;
|
||||
}
|
||||
void setStopRequested (bool req)
|
||||
{
|
||||
this->stop_requested = req;
|
||||
}
|
||||
|
||||
const SocketAddress& bindingAddress () const
|
||||
{
|
||||
return this->binding_address;
|
||||
}
|
||||
void setBindingAddress (const SocketAddress& address)
|
||||
{
|
||||
QSE_ASSERT (this->server_serving == false);
|
||||
this->binding_address = address;
|
||||
}
|
||||
|
||||
qse_size_t maxConnections () const
|
||||
{
|
||||
return this->max_connections;
|
||||
}
|
||||
void setMaxConnections (qse_size_t mc)
|
||||
{
|
||||
// don't disconnect client connections
|
||||
// establised before maxConn is set.
|
||||
// 0 means there's no restriction over
|
||||
// the number of connection.
|
||||
this->max_connections = mc;
|
||||
}
|
||||
|
||||
qse_size_t clientCount () const
|
||||
{
|
||||
return this->client_list.getSize();
|
||||
}
|
||||
qse_size_t connectionCount () const
|
||||
{
|
||||
return this->client_list.getSize();
|
||||
}
|
||||
|
||||
qse_size_t threadStackSize () const
|
||||
{
|
||||
return this->thread_stack_size;
|
||||
}
|
||||
|
||||
void setThreadStackSize (qse_size_t tss)
|
||||
{
|
||||
this->thread_stack_size = tss;
|
||||
}
|
||||
|
||||
bool shouldReopenSocketUponError () const
|
||||
{
|
||||
return this->reopen_socket_upon_error;
|
||||
}
|
||||
|
||||
void setReopenSocketUponError (bool v)
|
||||
{
|
||||
this->reopen_socket_upon_error = v;
|
||||
}
|
||||
|
||||
protected:
|
||||
class Client: public QSE::Thread
|
||||
{
|
||||
public:
|
||||
friend class TcpServer;
|
||||
|
||||
Client (TcpServer* server);
|
||||
|
||||
int run ();
|
||||
int stop () QSE_CPP_NOEXCEPT;
|
||||
|
||||
private:
|
||||
TcpServer* server;
|
||||
QSE::Socket socket;
|
||||
SocketAddress address;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
friend class TcpServer::Client;
|
||||
virtual int handle_client (Socket* sock, SocketAddress* addr) = 0;
|
||||
|
||||
private:
|
||||
void delete_dead_clients ();
|
||||
void delete_all_clients ();
|
||||
int open_tcp_socket (Socket& socket, bool winsock_inheritable, int* err_code);
|
||||
};
|
||||
|
||||
QSE_END_NAMESPACE(QSE)
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user