aboutsummaryrefslogtreecommitdiff
path: root/src/tcpsocket.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/tcpsocket.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 '')
-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