summaryrefslogtreecommitdiff
path: root/src/stable/tcpserversocket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/stable/tcpserversocket.cpp')
-rw-r--r--src/stable/tcpserversocket.cpp278
1 files changed, 139 insertions, 139 deletions
diff --git a/src/stable/tcpserversocket.cpp b/src/stable/tcpserversocket.cpp
index 91da199..aed7699 100644
--- a/src/stable/tcpserversocket.cpp
+++ b/src/stable/tcpserversocket.cpp
@@ -28,230 +28,230 @@
28namespace Bu { subExceptionDef( TcpServerSocketException ) } 28namespace Bu { subExceptionDef( TcpServerSocketException ) }
29 29
30Bu::TcpServerSocket::TcpServerSocket( int nPort, int nPoolSize ) : 30Bu::TcpServerSocket::TcpServerSocket( int nPort, int nPoolSize ) :
31 nPort( nPort ) 31 nPort( nPort )
32{ 32{
33#ifdef WIN32 33#ifdef WIN32
34 Bu::Winsock2::getInstance(); 34 Bu::Winsock2::getInstance();
35#endif 35#endif
36 36
37 /* Create the socket and set it up to accept connections. */ 37 /* Create the socket and set it up to accept connections. */
38 struct sockaddr_in name; 38 struct sockaddr_in name;
39 39
40 /* Give the socket a name. */ 40 /* Give the socket a name. */
41 name.sin_family = AF_INET; 41 name.sin_family = AF_INET;
42 name.sin_port = bu_htons( nPort ); 42 name.sin_port = bu_htons( nPort );
43 43
44 // I think this specifies who we will accept connections from, 44 // I think this specifies who we will accept connections from,
45 // a good thing to make configurable later on 45 // a good thing to make configurable later on
46 name.sin_addr.s_addr = bu_htonl( INADDR_ANY ); 46 name.sin_addr.s_addr = bu_htonl( INADDR_ANY );
47 47
48 startServer( name, nPoolSize ); 48 startServer( name, nPoolSize );
49} 49}
50 50
51Bu::TcpServerSocket::TcpServerSocket(const String &sAddr,int nPort, int nPoolSize) : 51Bu::TcpServerSocket::TcpServerSocket(const String &sAddr,int nPort, int nPoolSize) :
52 nPort( nPort ) 52 nPort( nPort )
53{ 53{
54#ifdef WIN32 54#ifdef WIN32
55 Bu::Winsock2::getInstance(); 55 Bu::Winsock2::getInstance();
56#endif 56#endif
57 57
58 /* Create the socket and set it up to accept connections. */ 58 /* Create the socket and set it up to accept connections. */
59 struct sockaddr_in name; 59 struct sockaddr_in name;
60 60
61 /* Give the socket a name. */ 61 /* Give the socket a name. */
62 name.sin_family = AF_INET; 62 name.sin_family = AF_INET;
63 63
64 name.sin_port = bu_htons( nPort ); 64 name.sin_port = bu_htons( nPort );
65 65
66#ifdef WIN32 66#ifdef WIN32
67 name.sin_addr.s_addr = bu_inet_addr( sAddr.getStr() ); 67 name.sin_addr.s_addr = bu_inet_addr( sAddr.getStr() );
68#else 68#else
69 inet_aton( sAddr.getStr(), &name.sin_addr ); 69 inet_aton( sAddr.getStr(), &name.sin_addr );
70#endif 70#endif
71 71
72 startServer( name, nPoolSize ); 72 startServer( name, nPoolSize );
73} 73}
74 74
75Bu::TcpServerSocket::TcpServerSocket( socket_t nServer, bool bInit, int nPoolSize ) : 75Bu::TcpServerSocket::TcpServerSocket( socket_t nServer, bool bInit, int nPoolSize ) :
76 nServer( nServer ), 76 nServer( nServer ),
77 nPort( 0 ) 77 nPort( 0 )
78{ 78{
79#ifdef WIN32 79#ifdef WIN32
80 Bu::Winsock2::getInstance(); 80 Bu::Winsock2::getInstance();
81#endif 81#endif
82 82
83 if( bInit ) 83 if( bInit )
84 { 84 {
85 struct sockaddr name; 85 struct sockaddr name;
86 socklen_t namelen = sizeof(name); 86 socklen_t namelen = sizeof(name);
87 getpeername( nServer, &name, &namelen ); 87 getpeername( nServer, &name, &namelen );
88 88
89 initServer( *((sockaddr_in *)&name), nPoolSize ); 89 initServer( *((sockaddr_in *)&name), nPoolSize );
90 } 90 }
91 else 91 else
92 { 92 {
93 FD_ZERO( &fdActive ); 93 FD_ZERO( &fdActive );
94 FD_SET( nServer, &fdActive ); 94 FD_SET( nServer, &fdActive );
95 } 95 }
96} 96}
97 97
98Bu::TcpServerSocket::TcpServerSocket( const TcpServerSocket &rSrc ) 98Bu::TcpServerSocket::TcpServerSocket( const TcpServerSocket &rSrc )
99{ 99{
100#ifdef WIN32 100#ifdef WIN32
101 Bu::Winsock2::getInstance(); 101 Bu::Winsock2::getInstance();
102#endif 102#endif
103 103
104 nServer = dup( rSrc.nServer ); 104 nServer = dup( rSrc.nServer );
105 nPort = rSrc.nPort; 105 nPort = rSrc.nPort;
106 FD_ZERO( &fdActive ); 106 FD_ZERO( &fdActive );
107 FD_SET( nServer, &fdActive ); 107 FD_SET( nServer, &fdActive );
108} 108}
109 109
110Bu::TcpServerSocket::~TcpServerSocket() 110Bu::TcpServerSocket::~TcpServerSocket()
111{ 111{
112#ifdef WIN32 112#ifdef WIN32
113 if( nServer != INVALID_SOCKET ) 113 if( nServer != INVALID_SOCKET )
114#else 114#else
115 if( nServer > -1 ) 115 if( nServer > -1 )
116#endif 116#endif
117 ::close( nServer ); 117 ::close( nServer );
118} 118}
119 119
120void Bu::TcpServerSocket::startServer( struct sockaddr_in &name, int nPoolSize ) 120void Bu::TcpServerSocket::startServer( struct sockaddr_in &name, int nPoolSize )
121{ 121{
122 /* Create the socket. */ 122 /* Create the socket. */
123 nServer = bu_socket( PF_INET, SOCK_STREAM, 0 ); 123 nServer = bu_socket( PF_INET, SOCK_STREAM, 0 );
124 124
125#ifdef WIN32 125#ifdef WIN32
126 if( nServer == INVALID_SOCKET ) 126 if( nServer == INVALID_SOCKET )
127#else 127#else
128 if( nServer < 0 ) 128 if( nServer < 0 )
129#endif 129#endif
130 { 130 {
131 throw Bu::TcpServerSocketException("Couldn't create a listen socket."); 131 throw Bu::TcpServerSocketException("Couldn't create a listen socket.");
132 } 132 }
133 133
134 int opt = 1; 134 int opt = 1;
135 bu_setsockopt( 135 bu_setsockopt(
136 nServer, 136 nServer,
137 SOL_SOCKET, 137 SOL_SOCKET,
138 SO_REUSEADDR, 138 SO_REUSEADDR,
139 (char *)&opt, 139 (char *)&opt,
140 sizeof( opt ) 140 sizeof( opt )
141 ); 141 );
142 142
143 initServer( name, nPoolSize ); 143 initServer( name, nPoolSize );
144} 144}
145 145
146void Bu::TcpServerSocket::initServer( struct sockaddr_in &name, int nPoolSize ) 146void Bu::TcpServerSocket::initServer( struct sockaddr_in &name, int nPoolSize )
147{ 147{
148 if( bu_bind( nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 ) 148 if( bu_bind( nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 )
149 { 149 {
150 throw Bu::TcpServerSocketException("Couldn't bind to the listen socket."); 150 throw Bu::TcpServerSocketException("Couldn't bind to the listen socket.");
151 } 151 }
152 152
153 if( bu_listen( nServer, nPoolSize ) < 0 ) 153 if( bu_listen( nServer, nPoolSize ) < 0 )
154 { 154 {
155 throw Bu::TcpServerSocketException( 155 throw Bu::TcpServerSocketException(
156 "Couldn't begin listening to the server socket." 156 "Couldn't begin listening to the server socket."
157 ); 157 );
158 } 158 }
159 159
160 FD_ZERO( &fdActive ); 160 FD_ZERO( &fdActive );
161 /* Initialize the set of active sockets. */ 161 /* Initialize the set of active sockets. */
162 FD_SET( nServer, &fdActive ); 162 FD_SET( nServer, &fdActive );
163} 163}
164 164
165int Bu::TcpServerSocket::getSocket() 165int Bu::TcpServerSocket::getSocket()
166{ 166{
167 return nServer; 167 return nServer;
168} 168}
169 169
170int Bu::TcpServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) 170int Bu::TcpServerSocket::accept( int nTimeoutSec, int nTimeoutUSec )
171{ 171{
172 fd_set fdRead = fdActive; 172 fd_set fdRead = fdActive;
173 173
174 struct timeval xT; 174 struct timeval xT;
175 175
176 xT.tv_sec = nTimeoutSec; 176 xT.tv_sec = nTimeoutSec;
177 xT.tv_usec = nTimeoutUSec; 177 xT.tv_usec = nTimeoutUSec;
178 178
179 if( TEMP_FAILURE_RETRY( 179 if( TEMP_FAILURE_RETRY(
180 bu_select( nServer+1, &fdRead, NULL, NULL, &xT )) < 0 ) 180 bu_select( nServer+1, &fdRead, NULL, NULL, &xT )) < 0 )
181 { 181 {
182 throw Bu::TcpServerSocketException( 182 throw Bu::TcpServerSocketException(
183 "Error scanning for new connections: %s", strerror( errno ) 183 "Error scanning for new connections: %s", strerror( errno )
184 ); 184 );
185 } 185 }
186 186
187 if( FD_ISSET( nServer, &fdRead ) ) 187 if( FD_ISSET( nServer, &fdRead ) )
188 { 188 {
189 struct sockaddr_in clientname; 189 struct sockaddr_in clientname;
190 socklen_t size; 190 socklen_t size;
191 int nClient; 191 int nClient;
192 192
193 size = sizeof( clientname ); 193 size = sizeof( clientname );
194#ifdef WIN32 194#ifdef WIN32
195 nClient = bu_accept( nServer, (struct sockaddr *)&clientname, &size); 195 nClient = bu_accept( nServer, (struct sockaddr *)&clientname, &size);
196#else /* not-WIN32 */ 196#else /* not-WIN32 */
197#ifdef __CYGWIN__ 197#ifdef __CYGWIN__
198 nClient = ::accept( nServer, (struct sockaddr *)&clientname, 198 nClient = ::accept( nServer, (struct sockaddr *)&clientname,
199 (int *)&size 199 (int *)&size
200 ); 200 );
201#else /* not-cygwin */ 201#else /* not-cygwin */
202#ifdef __APPLE__ 202#ifdef __APPLE__
203 nClient = ::accept( nServer, (struct sockaddr *)&clientname, (socklen_t*)&size ); 203 nClient = ::accept( nServer, (struct sockaddr *)&clientname, (socklen_t*)&size );
204#else /* linux */ 204#else /* linux */
205 nClient = ::accept( nServer, (struct sockaddr *)&clientname, &size ); 205 nClient = ::accept( nServer, (struct sockaddr *)&clientname, &size );
206#endif /* __APPLE__ */ 206#endif /* __APPLE__ */
207#endif /* __CYGWIN__ */ 207#endif /* __CYGWIN__ */
208#endif /* WIN32 */ 208#endif /* WIN32 */
209 if( nClient < 0 ) 209 if( nClient < 0 )
210 { 210 {
211 throw Bu::TcpServerSocketException( 211 throw Bu::TcpServerSocketException(
212 "Error accepting a new connection: %s", strerror( errno ) 212 "Error accepting a new connection: %s", strerror( errno )
213 ); 213 );
214 } 214 }
215 215
216#ifndef WIN32 216#ifndef WIN32
217 char tmpa[20]; 217 char tmpa[20];
218 inet_ntop( AF_INET, (void *)&clientname.sin_addr, tmpa, 20 ); 218 inet_ntop( AF_INET, (void *)&clientname.sin_addr, tmpa, 20 );
219 //"New connection from host %s, port %hd.", 219 //"New connection from host %s, port %hd.",
220 // tmpa, ntohs (clientname.sin_port) ); 220 // tmpa, ntohs (clientname.sin_port) );
221#endif 221#endif
222 222
223 { 223 {
224#ifndef WIN32 224#ifndef WIN32
225 int flags; 225 int flags;
226 flags = fcntl( nClient, F_GETFL, 0 ); 226 flags = fcntl( nClient, F_GETFL, 0 );
227 flags |= O_NONBLOCK; 227 flags |= O_NONBLOCK;
228 if( fcntl( nClient, F_SETFL, flags ) < 0) 228 if( fcntl( nClient, F_SETFL, flags ) < 0)
229 { 229 {
230 throw Bu::TcpServerSocketException( 230 throw Bu::TcpServerSocketException(
231 "Error setting option on client socket: %s", 231 "Error setting option on client socket: %s",
232 strerror( errno ) 232 strerror( errno )
233 ); 233 );
234 } 234 }
235#else 235#else
236 //------------------------- 236 //-------------------------
237 // Set the socket I/O mode: In this case FIONBIO 237 // Set the socket I/O mode: In this case FIONBIO
238 // enables or disables the blocking mode for the 238 // enables or disables the blocking mode for the
239 // socket based on the numerical value of iMode. 239 // socket based on the numerical value of iMode.
240 // If iMode = 0, blocking is enabled; 240 // If iMode = 0, blocking is enabled;
241 // If iMode != 0, non-blocking mode is enabled. 241 // If iMode != 0, non-blocking mode is enabled.
242 u_long iMode = 1; 242 u_long iMode = 1;
243 bu_ioctlsocket(nClient, FIONBIO, &iMode); 243 bu_ioctlsocket(nClient, FIONBIO, &iMode);
244#endif 244#endif
245 } 245 }
246 246
247 return nClient; 247 return nClient;
248 } 248 }
249 249
250 return -1; 250 return -1;
251} 251}
252 252
253int Bu::TcpServerSocket::getPort() 253int Bu::TcpServerSocket::getPort()
254{ 254{
255 return nPort; 255 return nPort;
256} 256}
257 257