aboutsummaryrefslogtreecommitdiff
path: root/src/tcpsocket.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2011-01-10 21:04:17 +0000
committerMike Buland <eichlan@xagasoft.com>2011-01-10 21:04:17 +0000
commit2ba3f84ab559da02a11aa000b3cecb3b3668af61 (patch)
tree266f450b512f607ec54d54af4fa8c13fdbe7ef91 /src/tcpsocket.cpp
parentea18007633b31901f2ae275cc0576c3f7ce99fc9 (diff)
parent3611f253f6fdfa4954d374ab85ddaa7f799c130c (diff)
downloadlibbu++-2ba3f84ab559da02a11aa000b3cecb3b3668af61.tar.gz
libbu++-2ba3f84ab559da02a11aa000b3cecb3b3668af61.tar.bz2
libbu++-2ba3f84ab559da02a11aa000b3cecb3b3668af61.tar.xz
libbu++-2ba3f84ab559da02a11aa000b3cecb3b3668af61.zip
Merged in the core branch. This is a major update that fixes many things, and
changes many others, including source files that were deleted and renamed. Before doing this update, I reccomend a full clean, or even a fresh checkout. Things to note, most outstanding about this update: - Bu::Socket was changed to Bu::TcpSocket and the default mode is blocking. - All templatized container classes are SharedCore now, which is good, but SharedCore is inherently non-reentrant safe. However, all SharedCore classes have a "clone" function that return a non-shared copy of the object, safe for passing into a reentrant safe function accessing shared memory.
Diffstat (limited to '')
-rw-r--r--src/tcpsocket.cpp (renamed from src/socket.cpp)148
1 files changed, 76 insertions, 72 deletions
diff --git a/src/socket.cpp b/src/tcpsocket.cpp
index baf3be3..bbd9cf5 100644
--- a/src/socket.cpp
+++ b/src/tcpsocket.cpp
@@ -14,7 +14,7 @@
14#include <sys/time.h> 14#include <sys/time.h>
15#include <errno.h> 15#include <errno.h>
16#include <fcntl.h> 16#include <fcntl.h>
17#include "bu/socket.h" 17#include "bu/tcpsocket.h"
18 18
19#include "bu/config.h" 19#include "bu/config.h"
20 20
@@ -29,10 +29,10 @@
29 29
30#define RBS (1024*2) 30#define RBS (1024*2)
31 31
32namespace Bu { subExceptionDef( SocketException ) } 32namespace Bu { subExceptionDef( TcpSocketException ) }
33 33
34Bu::Socket::Socket( int nSocket ) : 34Bu::TcpSocket::TcpSocket( int nTcpSocket ) :
35 nSocket( nSocket ), 35 nTcpSocket( nTcpSocket ),
36 bActive( true ), 36 bActive( true ),
37 bBlocking( true ) 37 bBlocking( true )
38{ 38{
@@ -42,8 +42,9 @@ Bu::Socket::Socket( int nSocket ) :
42 setAddress(); 42 setAddress();
43} 43}
44 44
45Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) : 45Bu::TcpSocket::TcpSocket( const Bu::FString &sAddr, int nPort, int nTimeout,
46 nSocket( 0 ), 46 bool bBlocking ) :
47 nTcpSocket( 0 ),
47 bActive( false ), 48 bActive( false ),
48 bBlocking( true ) 49 bBlocking( true )
49{ 50{
@@ -52,9 +53,9 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) :
52#endif 53#endif
53 54
54 /* Create the socket. */ 55 /* Create the socket. */
55 nSocket = bu_socket( PF_INET, SOCK_STREAM, 0 ); 56 nTcpSocket = bu_socket( PF_INET, SOCK_STREAM, 0 );
56 57
57 if( nSocket < 0 ) 58 if( nTcpSocket < 0 )
58 { 59 {
59 throw ExceptionBase("Couldn't create socket.\n"); 60 throw ExceptionBase("Couldn't create socket.\n");
60 } 61 }
@@ -78,12 +79,12 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) :
78 sAddr.getStr(), ibuf, &aiHints, &pAddr )) != 0 ) 79 sAddr.getStr(), ibuf, &aiHints, &pAddr )) != 0 )
79 { 80 {
80 close(); 81 close();
81 throw Bu::SocketException("Couldn't resolve hostname %s (%s).\n", 82 throw Bu::TcpSocketException("Couldn't resolve hostname %s (%s).\n",
82 sAddr.getStr(), bu_gai_strerror(ret)); 83 sAddr.getStr(), bu_gai_strerror(ret));
83 } 84 }
84 85
85 bu_connect( 86 bu_connect(
86 nSocket, 87 nTcpSocket,
87 pAddr->ai_addr, 88 pAddr->ai_addr,
88 pAddr->ai_addrlen 89 pAddr->ai_addrlen
89 ); 90 );
@@ -101,17 +102,17 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) :
101 int retval; 102 int retval;
102 103
103 FD_ZERO(&rfds); 104 FD_ZERO(&rfds);
104 FD_SET(nSocket, &rfds); 105 FD_SET(nTcpSocket, &rfds);
105 FD_ZERO(&wfds); 106 FD_ZERO(&wfds);
106 FD_SET(nSocket, &wfds); 107 FD_SET(nTcpSocket, &wfds);
107 FD_ZERO(&efds); 108 FD_ZERO(&efds);
108 FD_SET(nSocket, &efds); 109 FD_SET(nTcpSocket, &efds);
109 110
110 struct timeval tv; 111 struct timeval tv;
111 tv.tv_sec = nTimeout; 112 tv.tv_sec = nTimeout;
112 tv.tv_usec = 0; 113 tv.tv_usec = 0;
113 114
114 retval = bu_select( nSocket+1, &rfds, &wfds, &efds, &tv ); 115 retval = bu_select( nTcpSocket+1, &rfds, &wfds, &efds, &tv );
115 116
116 if( retval == 0 ) 117 if( retval == 0 )
117 { 118 {
@@ -120,51 +121,54 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) :
120 } 121 }
121 read( NULL, 0 ); // See if we can get any errors out of the way early. 122 read( NULL, 0 ); // See if we can get any errors out of the way early.
122 } 123 }
124
125 if( bBlocking )
126 setBlocking( bBlocking );
123} 127}
124 128
125Bu::Socket::~Socket() 129Bu::TcpSocket::~TcpSocket()
126{ 130{
127 close(); 131 close();
128} 132}
129 133
130void Bu::Socket::close() 134void Bu::TcpSocket::close()
131{ 135{
132 if( bActive ) 136 if( bActive )
133 { 137 {
134#ifndef WIN32 138#ifndef WIN32
135 fsync( nSocket ); 139 fsync( nTcpSocket );
136#endif 140#endif
137#ifdef WIN32 141#ifdef WIN32
138 #ifndef SHUT_RDWR 142 #ifndef SHUT_RDWR
139 #define SHUT_RDWR (SD_BOTH) 143 #define SHUT_RDWR (SD_BOTH)
140 #endif 144 #endif
141#endif 145#endif
142 bu_shutdown( nSocket, SHUT_RDWR ); 146 bu_shutdown( nTcpSocket, SHUT_RDWR );
143 ::close( nSocket ); 147 ::close( nTcpSocket );
144 } 148 }
145 bActive = false; 149 bActive = false;
146} 150}
147 151
148size_t Bu::Socket::read( void *pBuf, size_t nBytes ) 152size_t Bu::TcpSocket::read( void *pBuf, size_t nBytes )
149{ 153{
150 fd_set rfds; 154 fd_set rfds;
151 FD_ZERO(&rfds); 155 FD_ZERO(&rfds);
152 FD_SET(nSocket, &rfds); 156 FD_SET(nTcpSocket, &rfds);
153 struct timeval tv = {0, 0}; 157 struct timeval tv = {0, 0};
154 if( bu_select( nSocket+1, &rfds, NULL, NULL, &tv ) < 0 ) 158 if( bu_select( nTcpSocket+1, &rfds, NULL, NULL, &tv ) < 0 )
155 { 159 {
156 int iErr = errno; 160 int iErr = errno;
157 close(); 161 close();
158 throw SocketException( SocketException::cRead, strerror(iErr) ); 162 throw TcpSocketException( TcpSocketException::cRead, strerror(iErr) );
159 } 163 }
160 if( FD_ISSET( nSocket, &rfds ) || bBlocking ) 164 if( FD_ISSET( nTcpSocket, &rfds ) || bBlocking )
161 { 165 {
162 int nRead = TEMP_FAILURE_RETRY( 166 int nRead = TEMP_FAILURE_RETRY(
163 bu_recv( nSocket, (char *) pBuf, nBytes, 0 ) ); 167 bu_recv( nTcpSocket, (char *) pBuf, nBytes, 0 ) );
164 if( nRead == 0 ) 168 if( nRead == 0 )
165 { 169 {
166 close(); 170 close();
167 throw SocketException( SocketException::cClosed, "Socket closed."); 171 throw TcpSocketException( TcpSocketException::cClosed, "TcpSocket closed.");
168 } 172 }
169 if( nRead < 0 ) 173 if( nRead < 0 )
170 { 174 {
@@ -176,14 +180,14 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes )
176 if( errno == ENETRESET || errno == ECONNRESET ) 180 if( errno == ENETRESET || errno == ECONNRESET )
177 { 181 {
178 close(); 182 close();
179 throw SocketException( SocketException::cClosed, 183 throw TcpSocketException( TcpSocketException::cClosed,
180 strerror(errno) ); 184 strerror(errno) );
181 } 185 }
182 if( errno == EAGAIN ) 186 if( errno == EAGAIN )
183 return 0; 187 return 0;
184 int iErr = errno; 188 int iErr = errno;
185 close(); 189 close();
186 throw SocketException( SocketException::cRead, strerror(iErr) ); 190 throw TcpSocketException( TcpSocketException::cRead, strerror(iErr) );
187#endif 191#endif
188 } 192 }
189 return nRead; 193 return nRead;
@@ -191,7 +195,7 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes )
191 return 0; 195 return 0;
192} 196}
193 197
194size_t Bu::Socket::read( void *pBuf, size_t nBytes, 198size_t Bu::TcpSocket::read( void *pBuf, size_t nBytes,
195 uint32_t nSec, uint32_t nUSec ) 199 uint32_t nSec, uint32_t nUSec )
196{ 200{
197 struct timeval tv; 201 struct timeval tv;
@@ -199,7 +203,7 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes,
199 203
200 fd_set rfds; 204 fd_set rfds;
201 FD_ZERO(&rfds); 205 FD_ZERO(&rfds);
202 FD_SET(nSocket, &rfds); 206 FD_SET(nTcpSocket, &rfds);
203 207
204#ifdef WIN32 208#ifdef WIN32
205 DWORD dwStart = GetTickCount(); 209 DWORD dwStart = GetTickCount();
@@ -216,7 +220,7 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes,
216 { 220 {
217 tv.tv_sec = nSec; 221 tv.tv_sec = nSec;
218 tv.tv_usec = nUSec; 222 tv.tv_usec = nUSec;
219 bu_select( nSocket+1, &rfds, NULL, NULL, &tv ); 223 bu_select( nTcpSocket+1, &rfds, NULL, NULL, &tv );
220 nRead += read( ((char *)pBuf)+nRead, nBytes-nRead ); 224 nRead += read( ((char *)pBuf)+nRead, nBytes-nRead );
221 if( nRead >= nBytes ) 225 if( nRead >= nBytes )
222 break; 226 break;
@@ -235,13 +239,13 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes,
235 return nRead; 239 return nRead;
236} 240}
237 241
238size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) 242size_t Bu::TcpSocket::write( const void *pBuf, size_t nBytes )
239{ 243{
240//#ifdef WIN32 244//#ifdef WIN32
241 int nWrote = TEMP_FAILURE_RETRY( 245 int nWrote = TEMP_FAILURE_RETRY(
242 bu_send( nSocket, (const char *) pBuf, nBytes, 0 ) ); 246 bu_send( nTcpSocket, (const char *) pBuf, nBytes, 0 ) );
243//#else 247//#else
244// int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) ); 248// int nWrote = TEMP_FAILURE_RETRY( ::write( nTcpSocket, pBuf, nBytes ) );
245//#endif 249//#endif
246 if( nWrote < 0 ) 250 if( nWrote < 0 )
247 { 251 {
@@ -252,19 +256,19 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes )
252#else 256#else
253 if( errno == EAGAIN ) return 0; 257 if( errno == EAGAIN ) return 0;
254#endif 258#endif
255 throw SocketException( SocketException::cWrite, strerror(errno) ); 259 throw TcpSocketException( TcpSocketException::cWrite, strerror(errno) );
256 } 260 }
257 return nWrote; 261 return nWrote;
258} 262}
259 263
260size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32_t nUSec ) 264size_t Bu::TcpSocket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32_t nUSec )
261{ 265{
262 struct timeval tv; 266 struct timeval tv;
263 size_t nWrote = 0; 267 size_t nWrote = 0;
264 268
265 fd_set wfds; 269 fd_set wfds;
266 FD_ZERO(&wfds); 270 FD_ZERO(&wfds);
267 FD_SET(nSocket, &wfds); 271 FD_SET(nTcpSocket, &wfds);
268 272
269#ifdef WIN32 273#ifdef WIN32
270 DWORD dwStart = GetTickCount(); 274 DWORD dwStart = GetTickCount();
@@ -281,7 +285,7 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32
281 { 285 {
282 tv.tv_sec = nSec; 286 tv.tv_sec = nSec;
283 tv.tv_usec = nUSec; 287 tv.tv_usec = nUSec;
284 bu_select( nSocket+1, NULL, &wfds, NULL, &tv ); 288 bu_select( nTcpSocket+1, NULL, &wfds, NULL, &tv );
285 nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote ); 289 nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote );
286 if( nWrote >= nBytes ) 290 if( nWrote >= nBytes )
287 break; 291 break;
@@ -300,101 +304,101 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32
300 return nWrote; 304 return nWrote;
301} 305}
302 306
303long Bu::Socket::tell() 307long Bu::TcpSocket::tell()
304{ 308{
305 throw UnsupportedException(); 309 throw UnsupportedException();
306} 310}
307 311
308void Bu::Socket::seek( long ) 312void Bu::TcpSocket::seek( long )
309{ 313{
310 throw UnsupportedException(); 314 throw UnsupportedException();
311} 315}
312 316
313void Bu::Socket::setPos( long ) 317void Bu::TcpSocket::setPos( long )
314{ 318{
315 throw UnsupportedException(); 319 throw UnsupportedException();
316} 320}
317 321
318void Bu::Socket::setPosEnd( long ) 322void Bu::TcpSocket::setPosEnd( long )
319{ 323{
320 throw UnsupportedException(); 324 throw UnsupportedException();
321} 325}
322 326
323bool Bu::Socket::isEos() 327bool Bu::TcpSocket::isEos()
324{ 328{
325 return !bActive; 329 return !bActive;
326} 330}
327 331
328bool Bu::Socket::canRead() 332bool Bu::TcpSocket::canRead()
329{ 333{
330 fd_set rfds; 334 fd_set rfds;
331 FD_ZERO(&rfds); 335 FD_ZERO(&rfds);
332 FD_SET(nSocket, &rfds); 336 FD_SET(nTcpSocket, &rfds);
333 struct timeval tv = { 0, 0 }; 337 struct timeval tv = { 0, 0 };
334 int retval = bu_select( nSocket+1, &rfds, NULL, NULL, &tv ); 338 int retval = bu_select( nTcpSocket+1, &rfds, NULL, NULL, &tv );
335 if( retval == -1 ) 339 if( retval == -1 )
336 throw SocketException( 340 throw TcpSocketException(
337 SocketException::cBadRead, 341 TcpSocketException::cBadRead,
338 "Bad Read error" 342 "Bad Read error"
339 ); 343 );
340 344
341 if( !FD_ISSET( nSocket, &rfds ) ) 345 if( !FD_ISSET( nTcpSocket, &rfds ) )
342 return false; 346 return false;
343 return true; 347 return true;
344} 348}
345 349
346bool Bu::Socket::canWrite() 350bool Bu::TcpSocket::canWrite()
347{ 351{
348 fd_set wfds; 352 fd_set wfds;
349 FD_ZERO(&wfds); 353 FD_ZERO(&wfds);
350 FD_SET(nSocket, &wfds); 354 FD_SET(nTcpSocket, &wfds);
351 struct timeval tv = { 0, 0 }; 355 struct timeval tv = { 0, 0 };
352 int retval = bu_select( nSocket+1, NULL, &wfds, NULL, &tv ); 356 int retval = bu_select( nTcpSocket+1, NULL, &wfds, NULL, &tv );
353 if( retval == -1 ) 357 if( retval == -1 )
354 throw SocketException( 358 throw TcpSocketException(
355 SocketException::cBadRead, 359 TcpSocketException::cBadRead,
356 "Bad Read error" 360 "Bad Read error"
357 ); 361 );
358 if( !FD_ISSET( nSocket, &wfds ) ) 362 if( !FD_ISSET( nTcpSocket, &wfds ) )
359 return false; 363 return false;
360 return true; 364 return true;
361} 365}
362 366
363bool Bu::Socket::isReadable() 367bool Bu::TcpSocket::isReadable()
364{ 368{
365 return true; 369 return true;
366} 370}
367 371
368bool Bu::Socket::isWritable() 372bool Bu::TcpSocket::isWritable()
369{ 373{
370 return true; 374 return true;
371} 375}
372 376
373bool Bu::Socket::isSeekable() 377bool Bu::TcpSocket::isSeekable()
374{ 378{
375 return false; 379 return false;
376} 380}
377 381
378bool Bu::Socket::isBlocking() 382bool Bu::TcpSocket::isBlocking()
379{ 383{
380#ifndef WIN32 384#ifndef WIN32
381 return ((fcntl( nSocket, F_GETFL, 0 ) & O_NONBLOCK) != O_NONBLOCK); 385 return ((fcntl( nTcpSocket, F_GETFL, 0 ) & O_NONBLOCK) != O_NONBLOCK);
382#else 386#else
383 return false; 387 return false;
384#endif 388#endif
385} 389}
386 390
387void Bu::Socket::setBlocking( bool bBlocking ) 391void Bu::TcpSocket::setBlocking( bool bBlocking )
388{ 392{
389 this->bBlocking = bBlocking; 393 this->bBlocking = bBlocking;
390#ifndef WIN32 394#ifndef WIN32
391 if( bBlocking ) 395 if( bBlocking )
392 { 396 {
393 fcntl( nSocket, F_SETFL, fcntl( nSocket, F_GETFL, 0 ) & (~O_NONBLOCK) ); 397 fcntl( nTcpSocket, F_SETFL, fcntl( nTcpSocket, F_GETFL, 0 ) & (~O_NONBLOCK) );
394 } 398 }
395 else 399 else
396 { 400 {
397 fcntl( nSocket, F_SETFL, fcntl( nSocket, F_GETFL, 0 ) | O_NONBLOCK ); 401 fcntl( nTcpSocket, F_SETFL, fcntl( nTcpSocket, F_GETFL, 0 ) | O_NONBLOCK );
398 } 402 }
399#else 403#else
400 u_long iMode; 404 u_long iMode;
@@ -408,39 +412,39 @@ void Bu::Socket::setBlocking( bool bBlocking )
408 // socket based on the numerical value of iMode. 412 // socket based on the numerical value of iMode.
409 // If iMode = 0, blocking is enabled; 413 // If iMode = 0, blocking is enabled;
410 // If iMode != 0, non-blocking mode is enabled. 414 // If iMode != 0, non-blocking mode is enabled.
411 bu_ioctlsocket(nSocket, FIONBIO, &iMode); 415 bu_ioctlsocket(nTcpSocket, FIONBIO, &iMode);
412#endif 416#endif
413} 417}
414 418
415void Bu::Socket::setSize( long ) 419void Bu::TcpSocket::setSize( long )
416{ 420{
417} 421}
418 422
419void Bu::Socket::flush() 423void Bu::TcpSocket::flush()
420{ 424{
421} 425}
422 426
423bool Bu::Socket::isOpen() 427bool Bu::TcpSocket::isOpen()
424{ 428{
425 return bActive; 429 return bActive;
426} 430}
427 431
428void Bu::Socket::setAddress() 432void Bu::TcpSocket::setAddress()
429{ 433{
430 struct sockaddr_in addr; 434 struct sockaddr_in addr;
431 socklen_t len = sizeof(addr); 435 socklen_t len = sizeof(addr);
432 addr.sin_family = AF_INET; 436 addr.sin_family = AF_INET;
433 bu_getpeername( nSocket, (sockaddr *)(&addr), &len ); 437 bu_getpeername( nTcpSocket, (sockaddr *)(&addr), &len );
434 sAddress = bu_inet_ntoa( addr.sin_addr ); 438 sAddress = bu_inet_ntoa( addr.sin_addr );
435} 439}
436 440
437Bu::FString Bu::Socket::getAddress() const 441Bu::FString Bu::TcpSocket::getAddress() const
438{ 442{
439 return sAddress; 443 return sAddress;
440} 444}
441 445
442Bu::Socket::operator int() const 446Bu::TcpSocket::operator int() const
443{ 447{
444 return nSocket; 448 return nTcpSocket;
445} 449}
446 450