aboutsummaryrefslogtreecommitdiff
path: root/src/stable/tcpserversocket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/stable/tcpserversocket.cpp')
-rw-r--r--src/stable/tcpserversocket.cpp257
1 files changed, 0 insertions, 257 deletions
diff --git a/src/stable/tcpserversocket.cpp b/src/stable/tcpserversocket.cpp
deleted file mode 100644
index b1e3461..0000000
--- a/src/stable/tcpserversocket.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
1/*
2 * Copyright (C) 2007-2019 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#include "bu/config.h"
9
10#ifndef WIN32
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <netdb.h>
14 #include <arpa/inet.h>
15#endif
16
17#include <time.h>
18#include <string.h>
19#include <stdio.h>
20#include <errno.h>
21#include <stdlib.h>
22#include <unistd.h>
23#include <sys/types.h>
24//#include <termios.h>
25#include <fcntl.h>
26#include "bu/tcpserversocket.h"
27
28namespace Bu { subExceptionDef( TcpServerSocketException ) }
29
30Bu::TcpServerSocket::TcpServerSocket( 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::TcpServerSocket::TcpServerSocket(const String &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::TcpServerSocket::TcpServerSocket( socket_t 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::TcpServerSocket::TcpServerSocket( const TcpServerSocket &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::TcpServerSocket::~TcpServerSocket()
111{
112#ifdef WIN32
113 if( nServer != INVALID_SOCKET )
114#else
115 if( nServer > -1 )
116#endif
117 ::close( nServer );
118}
119
120void Bu::TcpServerSocket::startServer( struct sockaddr_in &name, int nPoolSize )
121{
122 /* Create the socket. */
123 nServer = bu_socket( PF_INET, SOCK_STREAM, 0 );
124
125#ifdef WIN32
126 if( nServer == INVALID_SOCKET )
127#else
128 if( nServer < 0 )
129#endif
130 {
131 throw Bu::TcpServerSocketException("Couldn't create a listen socket.");
132 }
133
134 int opt = 1;
135 bu_setsockopt(
136 nServer,
137 SOL_SOCKET,
138 SO_REUSEADDR,
139 (char *)&opt,
140 sizeof( opt )
141 );
142
143 initServer( name, nPoolSize );
144}
145
146void Bu::TcpServerSocket::initServer( struct sockaddr_in &name, int nPoolSize )
147{
148 if( bu_bind( nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 )
149 {
150 throw Bu::TcpServerSocketException("Couldn't bind to the listen socket.");
151 }
152
153 if( bu_listen( nServer, nPoolSize ) < 0 )
154 {
155 throw Bu::TcpServerSocketException(
156 "Couldn't begin listening to the server socket."
157 );
158 }
159
160 FD_ZERO( &fdActive );
161 /* Initialize the set of active sockets. */
162 FD_SET( nServer, &fdActive );
163}
164
165int Bu::TcpServerSocket::getSocket()
166{
167 return nServer;
168}
169
170int Bu::TcpServerSocket::accept( int nTimeoutSec, int nTimeoutUSec )
171{
172 fd_set fdRead = fdActive;
173
174 struct timeval xT;
175
176 xT.tv_sec = nTimeoutSec;
177 xT.tv_usec = nTimeoutUSec;
178
179 if( TEMP_FAILURE_RETRY(
180 bu_select( nServer+1, &fdRead, NULL, NULL, &xT )) < 0 )
181 {
182 throw Bu::TcpServerSocketException(
183 "Error scanning for new connections: %s", strerror( errno )
184 );
185 }
186
187 if( FD_ISSET( nServer, &fdRead ) )
188 {
189 struct sockaddr_in clientname;
190 socklen_t size;
191 int nClient;
192
193 size = sizeof( clientname );
194#ifdef WIN32
195 nClient = bu_accept( nServer, (struct sockaddr *)&clientname, &size);
196#else /* not-WIN32 */
197#ifdef __CYGWIN__
198 nClient = ::accept( nServer, (struct sockaddr *)&clientname,
199 (int *)&size
200 );
201#else /* not-cygwin */
202#ifdef __APPLE__
203 nClient = ::accept( nServer, (struct sockaddr *)&clientname, (socklen_t*)&size );
204#else /* linux */
205 nClient = ::accept( nServer, (struct sockaddr *)&clientname, &size );
206#endif /* __APPLE__ */
207#endif /* __CYGWIN__ */
208#endif /* WIN32 */
209 if( nClient < 0 )
210 {
211 throw Bu::TcpServerSocketException(
212 "Error accepting a new connection: %s", strerror( errno )
213 );
214 }
215
216#ifndef WIN32
217 char tmpa[20];
218 inet_ntop( AF_INET, (void *)&clientname.sin_addr, tmpa, 20 );
219 //"New connection from host %s, port %hd.",
220 // tmpa, ntohs (clientname.sin_port) );
221#endif
222
223 {
224#ifndef WIN32
225 int flags;
226 flags = fcntl( nClient, F_GETFL, 0 );
227 flags |= O_NONBLOCK;
228 if( fcntl( nClient, F_SETFL, flags ) < 0)
229 {
230 throw Bu::TcpServerSocketException(
231 "Error setting option on client socket: %s",
232 strerror( errno )
233 );
234 }
235#else
236 //-------------------------
237 // Set the socket I/O mode: In this case FIONBIO
238 // enables or disables the blocking mode for the
239 // socket based on the numerical value of iMode.
240 // If iMode = 0, blocking is enabled;
241 // If iMode != 0, non-blocking mode is enabled.
242 u_long iMode = 1;
243 bu_ioctlsocket(nClient, FIONBIO, &iMode);
244#endif
245 }
246
247 return nClient;
248 }
249
250 return -1;
251}
252
253int Bu::TcpServerSocket::getPort()
254{
255 return nPort;
256}
257