aboutsummaryrefslogtreecommitdiff
path: root/src/serversocket.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2010-10-16 03:02:11 +0000
committerMike Buland <eichlan@xagasoft.com>2010-10-16 03:02:11 +0000
commit9031e2af7dd4e65ec70890ee78a7cf600d1b2cc5 (patch)
tree17bc9d96b13d16d79385016c087321fc1267743f /src/serversocket.cpp
parent93c028162318a00b9bd03fc4a48383f830cc529d (diff)
downloadlibbu++-9031e2af7dd4e65ec70890ee78a7cf600d1b2cc5.tar.gz
libbu++-9031e2af7dd4e65ec70890ee78a7cf600d1b2cc5.tar.bz2
libbu++-9031e2af7dd4e65ec70890ee78a7cf600d1b2cc5.tar.xz
libbu++-9031e2af7dd4e65ec70890ee78a7cf600d1b2cc5.zip
Many, many changes. Documentation changes, renamed the socket class to
TcpSocket, fixed many other things, and finally removed ParamProc. Anything that needs it will now have to switch to OptParser.
Diffstat (limited to 'src/serversocket.cpp')
-rw-r--r--src/serversocket.cpp249
1 files changed, 0 insertions, 249 deletions
diff --git a/src/serversocket.cpp b/src/serversocket.cpp
deleted file mode 100644
index 87d0035..0000000
--- a/src/serversocket.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef WIN32
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <netdb.h>
12 #include <arpa/inet.h>
13#endif
14
15#include <time.h>
16#include <string.h>
17#include <stdio.h>
18#include <errno.h>
19#include <stdlib.h>
20#include <unistd.h>
21#include <sys/types.h>
22//#include <termios.h>
23#include <fcntl.h>
24#include "bu/serversocket.h"
25
26#include "bu/config.h"
27
28namespace Bu { subExceptionDef( ServerSocketException ) }
29
30Bu::ServerSocket::ServerSocket( int nPort, int nPoolSize ) :
31 nPort( nPort )
32{
33#ifdef WIN32
34 Bu::Winsock2::getInstance();
35#endif
36
37 /* Create the socket and set it up to accept connections. */
38 struct sockaddr_in name;
39
40 /* Give the socket a name. */
41 name.sin_family = AF_INET;
42 name.sin_port = bu_htons( nPort );
43
44 // I think this specifies who we will accept connections from,
45 // a good thing to make configurable later on
46 name.sin_addr.s_addr = bu_htonl( INADDR_ANY );
47
48 startServer( name, nPoolSize );
49}
50
51Bu::ServerSocket::ServerSocket(const FString &sAddr,int nPort, int nPoolSize) :
52 nPort( nPort )
53{
54#ifdef WIN32
55 Bu::Winsock2::getInstance();
56#endif
57
58 /* Create the socket and set it up to accept connections. */
59 struct sockaddr_in name;
60
61 /* Give the socket a name. */
62 name.sin_family = AF_INET;
63
64 name.sin_port = bu_htons( nPort );
65
66#ifdef WIN32
67 name.sin_addr.s_addr = bu_inet_addr( sAddr.getStr() );
68#else
69 inet_aton( sAddr.getStr(), &name.sin_addr );
70#endif
71
72 startServer( name, nPoolSize );
73}
74
75Bu::ServerSocket::ServerSocket( int nServer, bool bInit, int nPoolSize ) :
76 nServer( nServer ),
77 nPort( 0 )
78{
79#ifdef WIN32
80 Bu::Winsock2::getInstance();
81#endif
82
83 if( bInit )
84 {
85 struct sockaddr name;
86 socklen_t namelen = sizeof(name);
87 getpeername( nServer, &name, &namelen );
88
89 initServer( *((sockaddr_in *)&name), nPoolSize );
90 }
91 else
92 {
93 FD_ZERO( &fdActive );
94 FD_SET( nServer, &fdActive );
95 }
96}
97
98Bu::ServerSocket::ServerSocket( const ServerSocket &rSrc )
99{
100#ifdef WIN32
101 Bu::Winsock2::getInstance();
102#endif
103
104 nServer = dup( rSrc.nServer );
105 nPort = rSrc.nPort;
106 FD_ZERO( &fdActive );
107 FD_SET( nServer, &fdActive );
108}
109
110Bu::ServerSocket::~ServerSocket()
111{
112 if( nServer > -1 )
113 ::close( nServer );
114}
115
116void Bu::ServerSocket::startServer( struct sockaddr_in &name, int nPoolSize )
117{
118 /* Create the socket. */
119 nServer = bu_socket( PF_INET, SOCK_STREAM, 0 );
120
121 if( nServer < 0 )
122 {
123 throw Bu::ServerSocketException("Couldn't create a listen socket.");
124 }
125
126 int opt = 1;
127 bu_setsockopt(
128 nServer,
129 SOL_SOCKET,
130 SO_REUSEADDR,
131 (char *)&opt,
132 sizeof( opt )
133 );
134
135 initServer( name, nPoolSize );
136}
137
138void Bu::ServerSocket::initServer( struct sockaddr_in &name, int nPoolSize )
139{
140 if( bu_bind( nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 )
141 {
142 throw Bu::ServerSocketException("Couldn't bind to the listen socket.");
143 }
144
145 if( bu_listen( nServer, nPoolSize ) < 0 )
146 {
147 throw Bu::ServerSocketException(
148 "Couldn't begin listening to the server socket."
149 );
150 }
151
152 FD_ZERO( &fdActive );
153 /* Initialize the set of active sockets. */
154 FD_SET( nServer, &fdActive );
155}
156
157int Bu::ServerSocket::getSocket()
158{
159 return nServer;
160}
161
162int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec )
163{
164 fd_set fdRead = fdActive;
165
166 struct timeval xT;
167
168 xT.tv_sec = nTimeoutSec;
169 xT.tv_usec = nTimeoutUSec;
170
171 if( TEMP_FAILURE_RETRY(
172 bu_select( nServer+1, &fdRead, NULL, NULL, &xT )) < 0 )
173 {
174 throw Bu::ServerSocketException(
175 "Error scanning for new connections: %s", strerror( errno )
176 );
177 }
178
179 if( FD_ISSET( nServer, &fdRead ) )
180 {
181 struct sockaddr_in clientname;
182 socklen_t size;
183 int nClient;
184
185 size = sizeof( clientname );
186#ifdef WIN32
187 nClient = bu_accept( nServer, (struct sockaddr *)&clientname, &size);
188#else /* not-WIN32 */
189#ifdef __CYGWIN__
190 nClient = ::accept( nServer, (struct sockaddr *)&clientname,
191 (int *)&size
192 );
193#else /* not-cygwin */
194#ifdef __APPLE__
195 nClient = ::accept( nServer, (struct sockaddr *)&clientname, (socklen_t*)&size );
196#else /* linux */
197 nClient = ::accept( nServer, (struct sockaddr *)&clientname, &size );
198#endif /* __APPLE__ */
199#endif /* __CYGWIN__ */
200#endif /* WIN32 */
201 if( nClient < 0 )
202 {
203 throw Bu::ServerSocketException(
204 "Error accepting a new connection: %s", strerror( errno )
205 );
206 }
207
208#ifndef WIN32
209 char tmpa[20];
210 inet_ntop( AF_INET, (void *)&clientname.sin_addr, tmpa, 20 );
211 //"New connection from host %s, port %hd.",
212 // tmpa, ntohs (clientname.sin_port) );
213#endif
214
215 {
216#ifndef WIN32
217 int flags;
218 flags = fcntl( nClient, F_GETFL, 0 );
219 flags |= O_NONBLOCK;
220 if( fcntl( nClient, F_SETFL, flags ) < 0)
221 {
222 throw Bu::ServerSocketException(
223 "Error setting option on client socket: %s",
224 strerror( errno )
225 );
226 }
227#else
228 //-------------------------
229 // Set the socket I/O mode: In this case FIONBIO
230 // enables or disables the blocking mode for the
231 // socket based on the numerical value of iMode.
232 // If iMode = 0, blocking is enabled;
233 // If iMode != 0, non-blocking mode is enabled.
234 u_long iMode = 1;
235 bu_ioctlsocket(nClient, FIONBIO, &iMode);
236#endif
237 }
238
239 return nClient;
240 }
241
242 return -1;
243}
244
245int Bu::ServerSocket::getPort()
246{
247 return nPort;
248}
249