aboutsummaryrefslogtreecommitdiff
path: root/src/server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.cpp')
-rw-r--r--src/server.cpp96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/server.cpp b/src/server.cpp
new file mode 100644
index 0000000..d07a597
--- /dev/null
+++ b/src/server.cpp
@@ -0,0 +1,96 @@
1#include "bu/server.h"
2#include <errno.h>
3#include "bu/serversocket.h"
4#include "bu/client.h"
5#include "bu/socket.h"
6
7Bu::Server::Server() :
8 nTimeoutSec( 0 ),
9 nTimeoutUSec( 0 )
10{
11 FD_ZERO( &fdActive );
12}
13
14Bu::Server::~Server()
15{
16}
17
18void Bu::Server::addPort( int nPort, int nPoolSize )
19{
20 ServerSocket *s = new ServerSocket( nPort, nPoolSize );
21 int nSocket = s->getSocket();
22 FD_SET( nSocket, &fdActive );
23 hServers.insert( nSocket, s );
24}
25
26void Bu::Server::addPort( const FString &sAddr, int nPort, int nPoolSize )
27{
28 ServerSocket *s = new ServerSocket( sAddr, nPort, nPoolSize );
29 int nSocket = s->getSocket();
30 FD_SET( nSocket, &fdActive );
31 hServers.insert( nSocket, s );
32}
33
34void Bu::Server::setTimeout( int nTimeoutSec, int nTimeoutUSec )
35{
36 this->nTimeoutSec = nTimeoutSec;
37 this->nTimeoutUSec = nTimeoutUSec;
38}
39
40void Bu::Server::scan()
41{
42 struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec };
43
44 fd_set fdRead = fdActive;
45 fd_set fdWrite = fdActive;
46 fd_set fdException = fdActive;
47
48 if( TEMP_FAILURE_RETRY( select( FD_SETSIZE, &fdRead, NULL, &fdException, &xTimeout ) ) < 0 )
49 {
50 throw ExceptionBase("Error attempting to scan open connections.");
51 }
52
53 for( int j = 0; j < FD_SETSIZE; j++ )
54 {
55 if( FD_ISSET( j, &fdRead ) )
56 {
57 if( hServers.has( j ) )
58 {
59 ServerSocket *pSrv = hServers.get( j );
60 addClient( pSrv->accept(), pSrv->getPort() );
61 }
62 else
63 {
64 Client *pClient = hClients.get( j );
65 pClient->processInput();
66 if( !pClient->isOpen() )
67 {
68 onClosedConnection( pClient );
69 hClients.erase( j );
70 FD_CLR( j, &fdActive );
71 }
72 }
73 }
74 }
75
76 // Now we just try to write all the pending data on all the sockets.
77 // this could be done better eventually, if we care about the socket
78 // wanting to accept writes (using a select).
79 for( ClientHash::iterator i = hClients.begin(); i != hClients.end(); i++ )
80 {
81 (*i)->processOutput();
82 }
83}
84
85void Bu::Server::addClient( int nSocket, int nPort )
86{
87 FD_SET( nSocket, &fdActive );
88
89 Client *c = new Client(
90 new Bu::Socket( nSocket )
91 );
92 hClients.insert( nSocket, c );
93
94 onNewConnection( c, nPort );
95}
96