EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
BaseTCPServer Class Referenceabstract

Generic class for TCP server. More...

#include "TCPServer.h"

Inheritance diagram for BaseTCPServer:
Collaboration diagram for BaseTCPServer:

Public Member Functions

 BaseTCPServer ()
 Creates empty TCP server. More...
 
virtual ~BaseTCPServer ()
 Cleans server up. More...
 
uint16 GetPort () const
 
bool IsOpen () const
 
bool Open (uint16 port, char *errbuf=0)
 Start listening on specified port. More...
 
void Close ()
 Stops started listening. More...
 

Protected Member Functions

void StartLoop ()
 Starts worker thread. More...
 
void WaitLoop ()
 Waits for worker thread to terminate. More...
 
virtual bool Process ()
 Does periodical stuff to keep the server alive. More...
 
void ListenNewConnections ()
 Accepts all new connections. More...
 
virtual void CreateNewConnection (Socket *sock, uint32 rIP, uint16 rPort)=0
 Processes new connection. More...
 
void TCPServerLoop ()
 Loop for worker threads. More...
 

Static Protected Member Functions

static void * TCPServerLoop (void *arg)
 Loop for worker threads. More...
 

Protected Attributes

Mutex mMSock
 
SocketmSock
 
uint16 mPort
 
Mutex mMLoopRunning
 

Detailed Description

Generic class for TCP server.

Author
Zhur, Bloody.Rabbit

Definition at line 42 of file TCPServer.h.

Constructor & Destructor Documentation

BaseTCPServer::BaseTCPServer ( )

Creates empty TCP server.

Definition at line 37 of file TCPServer.cpp.

38 : mSock( nullptr ),
39  mPort( 0 )
40 {
41 }
Socket * mSock
Definition: TCPServer.h:122
uint16 mPort
Definition: TCPServer.h:124
BaseTCPServer::~BaseTCPServer ( )
virtual

Cleans server up.

Definition at line 43 of file TCPServer.cpp.

References Close(), sThread, and WaitLoop().

44 {
45  // Close socket
46  Close();
47  // Wait until worker thread terminates
48  WaitLoop();
49  /* delete thread here and remove from list */
50  sThread.RemoveThread(pthread_self());
51 }
void WaitLoop()
Waits for worker thread to terminate.
Definition: TCPServer.cpp:139
#define sThread
Definition: Threading.h:50
void Close()
Stops started listening.
Definition: TCPServer.cpp:118

Here is the call graph for this function:

Member Function Documentation

void BaseTCPServer::Close ( )

Stops started listening.

Definition at line 118 of file TCPServer.cpp.

References mMSock, mPort, mSock, and SafeDelete().

Referenced by main(), and ~BaseTCPServer().

119 {
120  MutexLock lock(mMSock);
121  SafeDelete(mSock);
122  mPort = 0;
123 }
A lock for a Lockable object.
Definition: Lock.h:70
Socket * mSock
Definition: TCPServer.h:122
Mutex mMSock
Definition: TCPServer.h:120
void SafeDelete(T *&p)
Deletes and nullifies a pointer.
Definition: SafeMem.h:83
uint16 mPort
Definition: TCPServer.h:124

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void BaseTCPServer::CreateNewConnection ( Socket sock,
uint32  rIP,
uint16  rPort 
)
protectedpure virtual

Processes new connection.

This function must be overloaded by children to process new connections. Called every time a new connection is accepted.

Implemented in EVETCPServer.

Referenced by ListenNewConnections().

Here is the caller graph for this function:

uint16 BaseTCPServer::GetPort ( ) const
inline
Returns
TCP port the server listens on.

Definition at line 55 of file TCPServer.h.

References mPort.

55 { return mPort; }
uint16 mPort
Definition: TCPServer.h:124
bool BaseTCPServer::IsOpen ( ) const
Returns
True if listening has been opened, false if not.

Definition at line 53 of file TCPServer.cpp.

References Mutex::Lock(), mMSock, mSock, and Mutex::Unlock().

Referenced by Open(), and Process().

54 {
55  mMSock.Lock();
56  bool ret = (mSock != nullptr);
57  mMSock.Unlock();
58  return ret;
59 }
Socket * mSock
Definition: TCPServer.h:122
Mutex mMSock
Definition: TCPServer.h:120
void Lock()
Locks the mutex.
Definition: Mutex.cpp:57
void Unlock()
Unlocks the mutex.
Definition: Mutex.cpp:75

Here is the call graph for this function:

Here is the caller graph for this function:

void BaseTCPServer::ListenNewConnections ( )
protected

Accepts all new connections.

Definition at line 156 of file TCPServer.cpp.

References Socket::accept(), CreateNewConnection(), Socket::fcntl(), mMSock, mSock, and Socket::setopt().

Referenced by Process().

157 {
158  Socket* sock(nullptr);
159  sockaddr_in from = sockaddr_in();
160  from.sin_family = AF_INET;
161  unsigned int fromlen = sizeof( from );
162  MutexLock lock( mMSock );
163 
164  while ((sock = mSock->accept((sockaddr*)&from, &fromlen))) {
165  sock->fcntl( F_SETFL, O_NONBLOCK );
166  unsigned int bufsize = 64 * 1024; // 64kbyte receive buffer, up from default of 8k
167  sock->setopt( SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof( bufsize ) );
168  // New TCP connection, this must consume the socket.
169  CreateNewConnection( sock, from.sin_addr.s_addr, ntohs( from.sin_port ) );
170  }
171 }
Simple wrapper for sockets.
Definition: Socket.h:34
A lock for a Lockable object.
Definition: Lock.h:70
Socket * mSock
Definition: TCPServer.h:122
Mutex mMSock
Definition: TCPServer.h:120
Socket * accept(sockaddr *addr, unsigned int *addrlen)
Definition: Socket.cpp:89
virtual void CreateNewConnection(Socket *sock, uint32 rIP, uint16 rPort)=0
Processes new connection.

Here is the call graph for this function:

Here is the caller graph for this function:

bool BaseTCPServer::Open ( uint16  port,
char *  errbuf = 0 
)

Start listening on specified port.

Parameters
[in]portPort on which listening should be started.
[out]errbufError buffer which receives description of error.
Returns
True if listening has been started successfully, false if not.

Definition at line 61 of file TCPServer.cpp.

References _log, Socket::bind(), Socket::fcntl(), IsOpen(), Socket::listen(), Mutex::Lock(), mMSock, mPort, mSock, SafeDelete(), Socket::setopt(), snprintf, SOCKET_ERROR, StartLoop(), TCPSRV_ERRBUF_SIZE, Mutex::Unlock(), and WaitLoop().

Referenced by main().

62 {
63  if (errbuf != nullptr)
64  errbuf[0] = 0;
65 
66  // mutex lock
67  MutexLock lock( mMSock );
68 
69  if (IsOpen()) {
70  _log(TCP_SERVER__ERROR, "Open() - Listening socket already open" );
71  if (errbuf != nullptr)
72  snprintf( errbuf, TCPSRV_ERRBUF_SIZE, "Listening socket already open" );
73  return false;
74  } else {
75  mMSock.Unlock();
76  WaitLoop();
77  mMSock.Lock();
78  }
79 
80  // Setting up TCP port for new TCP connections
81  mSock = new Socket( AF_INET, SOCK_STREAM, 0 );
82 
83  unsigned int reuse_addr = 1;
84  mSock->setopt( SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof( reuse_addr ) );
85 
86  // Setup internet address information.
87  // This is used with the bind() call
88  sockaddr_in address = sockaddr_in();
89  memset( &address, 0, sizeof( address ) );
90  address.sin_family = AF_INET;
91  address.sin_port = htons( port );
92  address.sin_addr.s_addr = htonl( INADDR_ANY );
93 
94  if (mSock->bind((sockaddr*)&address, sizeof(address)) < 0) {
95  _log(TCP_SERVER__ERROR, "Open()::bind() < 0" );
96  if (errbuf)
97  snprintf( errbuf, TCPSRV_ERRBUF_SIZE, "%s", strerror( errno ) );
98  SafeDelete( mSock );
99  return false;
100  }
101 
102  unsigned int bufsize = 64 * 1024; // 64kbyte receive buffer, up from default of 8k
103  mSock->setopt( SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof( bufsize ) );
104  mSock->fcntl( F_SETFL, O_NONBLOCK );
105  if (mSock->listen() == SOCKET_ERROR) {
106  _log(TCP_SERVER__ERROR, "Open()::listen() failed, Error: %s", strerror( errno ) );
107  if (errbuf)
108  snprintf( errbuf, TCPSRV_ERRBUF_SIZE, "%s", strerror( errno ) );
109  SafeDelete( mSock );
110  return false;
111  }
112 
113  mPort = port;
114  StartLoop();
115  return true;
116 }
Simple wrapper for sockets.
Definition: Socket.h:34
#define _log(type, fmt,...)
Definition: logsys.h:124
int listen(int backlog=SOMAXCONN)
Definition: Socket.cpp:84
void WaitLoop()
Waits for worker thread to terminate.
Definition: TCPServer.cpp:139
A lock for a Lockable object.
Definition: Lock.h:70
Socket * mSock
Definition: TCPServer.h:122
Mutex mMSock
Definition: TCPServer.h:120
int bind(const sockaddr *name, unsigned int namelen)
Definition: Socket.cpp:79
void Lock()
Locks the mutex.
Definition: Mutex.cpp:57
const uint32 TCPSRV_ERRBUF_SIZE
Definition: TCPServer.cpp:34
void SafeDelete(T *&p)
Deletes and nullifies a pointer.
Definition: SafeMem.h:83
#define snprintf
Definition: eve-compat.h:184
int setopt(int level, int optname, const void *optval, unsigned int optlen)
Definition: Socket.cpp:99
void Unlock()
Unlocks the mutex.
Definition: Mutex.cpp:75
uint16 mPort
Definition: TCPServer.h:124
#define SOCKET_ERROR
Definition: eve-compat.h:130
int fcntl(int cmd, long arg)
Definition: Socket.cpp:104
void StartLoop()
Starts worker thread.
Definition: TCPServer.cpp:125
bool IsOpen() const
Definition: TCPServer.cpp:53

Here is the call graph for this function:

Here is the caller graph for this function:

bool BaseTCPServer::Process ( )
protectedvirtual

Does periodical stuff to keep the server alive.

Returns
True if the server should be further processed, false if not (eg. error occurred).

Definition at line 146 of file TCPServer.cpp.

References IsOpen(), ListenNewConnections(), and mMSock.

Referenced by TCPServerLoop().

147 {
148  MutexLock lock( mMSock );
149  if (IsOpen()) {
151  return true;
152  }
153  return false;
154 }
A lock for a Lockable object.
Definition: Lock.h:70
Mutex mMSock
Definition: TCPServer.h:120
void ListenNewConnections()
Accepts all new connections.
Definition: TCPServer.cpp:156
bool IsOpen() const
Definition: TCPServer.cpp:53

Here is the call graph for this function:

Here is the caller graph for this function:

void BaseTCPServer::StartLoop ( )
protected

Starts worker thread.

This function just starts worker thread; it doesn't check whether there already is one running!

Definition at line 125 of file TCPServer.cpp.

References sThread, and TCPServerLoop().

Referenced by Open().

126 {
127  /* since there is only one instance of BaseTCPServer, we can create thread here instead
128  * of sending to Thread class for creation and management
129  * update this to use Thread class management (sThread) if management here becomes a problem.
130  */
131  sThread.CreateThread(TCPServerLoop, this);
132  /*
133  pthread_t thread;
134  pthread_create( &thread, nullptr, TCPServerLoop, this );
135  _log(THREAD__WARNING, "StartLoop() - Created thread ID 0x%X for TCPServerLoop", thread);
136  sThread.AddThread(thread);*/
137 }
void TCPServerLoop()
Loop for worker threads.
Definition: TCPServer.cpp:183
#define sThread
Definition: Threading.h:50

Here is the call graph for this function:

Here is the caller graph for this function:

void * BaseTCPServer::TCPServerLoop ( void *  arg)
staticprotected

Loop for worker threads.

This function only casts arg to BaseTCPServer and calls member TCPServerLoop().

Parameters
[in]argPointer to BaseTCPServer.

Definition at line 173 of file TCPServer.cpp.

References TCPServerLoop().

Referenced by TCPServerLoop().

174 {
175  BaseTCPServer* tcps = reinterpret_cast< BaseTCPServer* >( arg );
176  assert( tcps != nullptr );
177 
178  tcps->TCPServerLoop();
179 
180  return nullptr;
181 }
static void * TCPServerLoop(void *arg)
Loop for worker threads.
Definition: TCPServer.cpp:173
Generic class for TCP server.
Definition: TCPServer.h:42

Here is the call graph for this function:

Here is the caller graph for this function:

void BaseTCPServer::TCPServerLoop ( )
protected

Loop for worker threads.

Definition at line 183 of file TCPServer.cpp.

References GetTickCount(), Mutex::Lock(), mMLoopRunning, Process(), Sleep(), TCPSRV_LOOP_GRANULARITY, and Mutex::Unlock().

Referenced by StartLoop().

184 {
186  uint32 start = GetTickCount();
187  while (Process()) {
188  // do the stuff for thread sleeping
189  start = GetTickCount() - start;
190  if (TCPSRV_LOOP_GRANULARITY > start)
192  start = GetTickCount();
193  }
195 }
void Lock()
Locks the mutex.
Definition: Mutex.cpp:57
const uint32 TCPSRV_LOOP_GRANULARITY
Definition: TCPServer.cpp:35
uint32 GetTickCount()
Definition: eve-compat.cpp:39
Mutex mMLoopRunning
Definition: TCPServer.h:127
void Unlock()
Unlocks the mutex.
Definition: Mutex.cpp:75
unsigned __int32 uint32
Definition: eve-compat.h:50
void Sleep(uint32 x)
Definition: eve-compat.cpp:32
virtual bool Process()
Does periodical stuff to keep the server alive.
Definition: TCPServer.cpp:146

Here is the call graph for this function:

Here is the caller graph for this function:

void BaseTCPServer::WaitLoop ( )
protected

Waits for worker thread to terminate.

Definition at line 139 of file TCPServer.cpp.

References Mutex::Lock(), mMLoopRunning, and Mutex::Unlock().

Referenced by Open(), and ~BaseTCPServer().

140 {
141  //wait for running loop to stop.
144 }
void Lock()
Locks the mutex.
Definition: Mutex.cpp:57
Mutex mMLoopRunning
Definition: TCPServer.h:127
void Unlock()
Unlocks the mutex.
Definition: Mutex.cpp:75

Here is the call graph for this function:

Here is the caller graph for this function:

Member Data Documentation

Mutex BaseTCPServer::mMLoopRunning
mutableprotected

Worker thread acquires this mutex before it starts processing; used for thread synchronization.

Definition at line 127 of file TCPServer.h.

Referenced by TCPServerLoop(), and WaitLoop().

Mutex BaseTCPServer::mMSock
mutableprotected

Mutex to protect socket and associated variables.

Definition at line 120 of file TCPServer.h.

Referenced by Close(), IsOpen(), ListenNewConnections(), Open(), and Process().

uint16 BaseTCPServer::mPort
protected

Port the socket is listening on.

Definition at line 124 of file TCPServer.h.

Referenced by Close(), GetPort(), and Open().

Socket* BaseTCPServer::mSock
protected

Socket used for listening.

Definition at line 122 of file TCPServer.h.

Referenced by Close(), IsOpen(), ListenNewConnections(), and Open().


The documentation for this class was generated from the following files: