aboutsummaryrefslogtreecommitdiff
path: root/src/socket.cpp
diff options
context:
space:
mode:
authorDavid <david@xagasoft.com>2008-10-27 16:07:50 +0000
committerDavid <david@xagasoft.com>2008-10-27 16:07:50 +0000
commit61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9 (patch)
tree530a0d86ca1043dbc04cd7513bc5dd65768a266d /src/socket.cpp
parentf7e8658f2274044bb452492b1af7e2cd5f82082c (diff)
downloadlibbu++-61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9.tar.gz
libbu++-61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9.tar.bz2
libbu++-61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9.tar.xz
libbu++-61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9.zip
david - apparently windows prefers to dynamically load winsock and a couple other libraries, so I got it all compiling and working in windows, yay!... I tried to minimize the impact on the code: I made a DYNLOAD macro that evaluates to nothing on everything else, but runs the dynamic code if compiled for windows... also, apparently I had been randomly switching between ifdef and ifndef WIN32: so i made most of them ifdefs so it was less confusing...
Diffstat (limited to '')
-rw-r--r--src/socket.cpp90
1 files changed, 54 insertions, 36 deletions
diff --git a/src/socket.cpp b/src/socket.cpp
index aea66f8..ce16794 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -44,7 +44,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout )
44 bActive = false; 44 bActive = false;
45 45
46 /* Create the socket. */ 46 /* Create the socket. */
47 nSocket = socket( PF_INET, SOCK_STREAM, 0 ); 47 nSocket = DYNLOAD socket( PF_INET, SOCK_STREAM, 0 );
48 48
49 if( nSocket < 0 ) 49 if( nSocket < 0 )
50 { 50 {
@@ -68,7 +68,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout )
68 // If iMode = 0, blocking is enabled; 68 // If iMode = 0, blocking is enabled;
69 // If iMode != 0, non-blocking mode is enabled. 69 // If iMode != 0, non-blocking mode is enabled.
70 u_long iMode = 1; 70 u_long iMode = 1;
71 ioctlsocket(nSocket, FIONBIO, &iMode); 71 DYNLOAD ioctlsocket(nSocket, FIONBIO, &iMode);
72#endif 72#endif
73 73
74 /* Connect to the server. */ 74 /* Connect to the server. */
@@ -77,8 +77,8 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout )
77 struct hostent *hostinfo; 77 struct hostent *hostinfo;
78 78
79 xServerName.sin_family = AF_INET; 79 xServerName.sin_family = AF_INET;
80 xServerName.sin_port = htons( nPort ); 80 xServerName.sin_port = DYNLOAD htons( nPort );
81 hostinfo = gethostbyname( sAddr.getStr() ); 81 hostinfo = DYNLOAD gethostbyname( sAddr.getStr() );
82 if (hostinfo == NULL) 82 if (hostinfo == NULL)
83 { 83 {
84 throw Bu::SocketException("Couldn't resolve hostname.\n"); 84 throw Bu::SocketException("Couldn't resolve hostname.\n");
@@ -88,7 +88,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout )
88 88
89 //printf("Making actual connection..."); 89 //printf("Making actual connection...");
90 //fflush( stdout ); 90 //fflush( stdout );
91 connect( 91 DYNLOAD connect(
92 nSocket, 92 nSocket,
93 (struct sockaddr *)&xServerName, 93 (struct sockaddr *)&xServerName,
94 sizeof(xServerName) 94 sizeof(xServerName)
@@ -113,7 +113,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout )
113 tv.tv_sec = nTimeout; 113 tv.tv_sec = nTimeout;
114 tv.tv_usec = 0; 114 tv.tv_usec = 0;
115 115
116 retval = select( nSocket+1, &rfds, &wfds, &efds, &tv ); 116 retval = DYNLOAD select( nSocket+1, &rfds, &wfds, &efds, &tv );
117 117
118 if( retval == 0 ) 118 if( retval == 0 )
119 { 119 {
@@ -195,7 +195,12 @@ void Bu::Socket::read()
195 195
196size_t Bu::Socket::read( void *pBuf, size_t nBytes ) 196size_t Bu::Socket::read( void *pBuf, size_t nBytes )
197{ 197{
198#ifdef WIN32
199 int nRead = TEMP_FAILURE_RETRY(
200 DYNLOAD recv( nSocket, (char *) pBuf, nBytes, 0 ) );
201#else
198 int nRead = TEMP_FAILURE_RETRY( ::read( nSocket, pBuf, nBytes ) ); 202 int nRead = TEMP_FAILURE_RETRY( ::read( nSocket, pBuf, nBytes ) );
203#endif
199 if( nRead < 0 ) 204 if( nRead < 0 )
200 { 205 {
201 throw SocketException( SocketException::cRead, strerror(errno) ); 206 throw SocketException( SocketException::cRead, strerror(errno) );
@@ -213,35 +218,35 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes,
213 FD_ZERO(&rfds); 218 FD_ZERO(&rfds);
214 FD_SET(nSocket, &rfds); 219 FD_SET(nSocket, &rfds);
215 220
216#ifndef WIN32 221#ifdef WIN32
222 DWORD dwStart = GetTickCount();
223 uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000));
224 DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver;
225#else
217 struct timeval nt, ct; 226 struct timeval nt, ct;
218 gettimeofday( &nt, NULL ); 227 gettimeofday( &nt, NULL );
219 nt.tv_sec += nSec; 228 nt.tv_sec += nSec;
220 nt.tv_usec += nUSec; 229 nt.tv_usec += nUSec;
221#else
222 DWORD dwStart = GetTickCount();
223 uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000));
224 DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver;
225#endif 230#endif
226 231
227 for(;;) 232 for(;;)
228 { 233 {
229 tv.tv_sec = nSec; 234 tv.tv_sec = nSec;
230 tv.tv_usec = nUSec; 235 tv.tv_usec = nUSec;
231 select( nSocket+1, &rfds, NULL, NULL, &tv ); 236 DYNLOAD select( nSocket+1, &rfds, NULL, NULL, &tv );
232 nRead += read( ((char *)pBuf)+nRead, nBytes-nRead ); 237 nRead += read( ((char *)pBuf)+nRead, nBytes-nRead );
233 if( nRead >= nBytes ) 238 if( nRead >= nBytes )
234 break; 239 break;
235#ifndef WIN32 240#ifdef WIN32
241 DWORD dwNow = GetTickCount();
242 if( dwNow > dwEnd )
243 break;
244#else
236 gettimeofday( &ct, NULL ); 245 gettimeofday( &ct, NULL );
237 if( (ct.tv_sec > nt.tv_sec) || 246 if( (ct.tv_sec > nt.tv_sec) ||
238 (ct.tv_sec == nt.tv_sec && 247 (ct.tv_sec == nt.tv_sec &&
239 ct.tv_usec >= nt.tv_usec) ) 248 ct.tv_usec >= nt.tv_usec) )
240 break; 249 break;
241#else
242 DWORD dwNow = GetTickCount();
243 if( dwNow > dwEnd )
244 break;
245#endif 250#endif
246 } 251 }
247 return nRead; 252 return nRead;
@@ -249,7 +254,12 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes,
249 254
250size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) 255size_t Bu::Socket::write( const void *pBuf, size_t nBytes )
251{ 256{
257#ifdef WIN32
258 int nWrote = TEMP_FAILURE_RETRY(
259 DYNLOAD send( nSocket, (const char *) pBuf, nBytes, 0 ) );
260#else
252 int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) ); 261 int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) );
262#endif
253 if( nWrote < 0 ) 263 if( nWrote < 0 )
254 { 264 {
255 if( errno == EAGAIN ) return 0; 265 if( errno == EAGAIN ) return 0;
@@ -267,35 +277,35 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32
267 FD_ZERO(&wfds); 277 FD_ZERO(&wfds);
268 FD_SET(nSocket, &wfds); 278 FD_SET(nSocket, &wfds);
269 279
270#ifndef WIN32 280#ifdef WIN32
281 DWORD dwStart = GetTickCount();
282 uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000));
283 DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver;
284#else
271 struct timeval nt, ct; 285 struct timeval nt, ct;
272 gettimeofday( &nt, NULL ); 286 gettimeofday( &nt, NULL );
273 nt.tv_sec += nSec; 287 nt.tv_sec += nSec;
274 nt.tv_usec += nUSec; 288 nt.tv_usec += nUSec;
275#else
276 DWORD dwStart = GetTickCount();
277 uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000));
278 DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver;
279#endif 289#endif
280 290
281 for(;;) 291 for(;;)
282 { 292 {
283 tv.tv_sec = nSec; 293 tv.tv_sec = nSec;
284 tv.tv_usec = nUSec; 294 tv.tv_usec = nUSec;
285 select( nSocket+1, NULL, &wfds, NULL, &tv ); 295 DYNLOAD select( nSocket+1, NULL, &wfds, NULL, &tv );
286 nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote ); 296 nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote );
287 if( nWrote >= nBytes ) 297 if( nWrote >= nBytes )
288 break; 298 break;
289#ifndef WIN32 299#ifdef WIN32
300 DWORD dwNow = GetTickCount();
301 if( dwNow > dwEnd )
302 break;
303#else
290 gettimeofday( &ct, NULL ); 304 gettimeofday( &ct, NULL );
291 if( (ct.tv_sec > nt.tv_sec) || 305 if( (ct.tv_sec > nt.tv_sec) ||
292 (ct.tv_sec == nt.tv_sec && 306 (ct.tv_sec == nt.tv_sec &&
293 ct.tv_usec >= nt.tv_usec) ) 307 ct.tv_usec >= nt.tv_usec) )
294 break; 308 break;
295#else
296 DWORD dwNow = GetTickCount();
297 if( dwNow > dwEnd )
298 break;
299#endif 309#endif
300 } 310 }
301 return nWrote; 311 return nWrote;
@@ -332,13 +342,17 @@ bool Bu::Socket::canRead()
332 FD_ZERO(&rfds); 342 FD_ZERO(&rfds);
333 FD_SET(nSocket, &rfds); 343 FD_SET(nSocket, &rfds);
334 struct timeval tv = { 0, 0 }; 344 struct timeval tv = { 0, 0 };
335 int retval = select( nSocket+1, &rfds, NULL, NULL, &tv ); 345 int retval = DYNLOAD select( nSocket+1, &rfds, NULL, NULL, &tv );
336 if( retval == -1 ) 346 if( retval == -1 )
337 throw SocketException( 347 throw SocketException(
338 SocketException::cBadRead, 348 SocketException::cBadRead,
339 "Bad Read error" 349 "Bad Read error"
340 ); 350 );
351#ifdef WIN32
352 if( !DynamicWinsock2::DYN_FD_ISSET( nSocket, &rfds ) )
353#else
341 if( !FD_ISSET( nSocket, &rfds ) ) 354 if( !FD_ISSET( nSocket, &rfds ) )
355#endif
342 return false; 356 return false;
343 return true; 357 return true;
344} 358}
@@ -349,13 +363,17 @@ bool Bu::Socket::canWrite()
349 FD_ZERO(&wfds); 363 FD_ZERO(&wfds);
350 FD_SET(nSocket, &wfds); 364 FD_SET(nSocket, &wfds);
351 struct timeval tv = { 0, 0 }; 365 struct timeval tv = { 0, 0 };
352 int retval = select( nSocket+1, NULL, &wfds, NULL, &tv ); 366 int retval = DYNLOAD select( nSocket+1, NULL, &wfds, NULL, &tv );
353 if( retval == -1 ) 367 if( retval == -1 )
354 throw SocketException( 368 throw SocketException(
355 SocketException::cBadRead, 369 SocketException::cBadRead,
356 "Bad Read error" 370 "Bad Read error"
357 ); 371 );
372#ifdef WIN32
373 if( !DynamicWinsock2::DYN_FD_ISSET( nSocket, &wfds ) )
374#else
358 if( !FD_ISSET( nSocket, &wfds ) ) 375 if( !FD_ISSET( nSocket, &wfds ) )
376#endif
359 return false; 377 return false;
360 return true; 378 return true;
361} 379}
@@ -403,7 +421,7 @@ void Bu::Socket::setBlocking( bool bBlocking )
403 // socket based on the numerical value of iMode. 421 // socket based on the numerical value of iMode.
404 // If iMode = 0, blocking is enabled; 422 // If iMode = 0, blocking is enabled;
405 // If iMode != 0, non-blocking mode is enabled. 423 // If iMode != 0, non-blocking mode is enabled.
406 ioctlsocket(nSocket, FIONBIO, &iMode); 424 DYNLOAD ioctlsocket(nSocket, FIONBIO, &iMode);
407#endif 425#endif
408} 426}
409 427
@@ -416,20 +434,20 @@ bool Bu::Socket::isOpen()
416 return bActive; 434 return bActive;
417} 435}
418 436
419//#ifdef WIN32
420// typedef int socklen_t;
421//#endif
422
423void Bu::Socket::setAddress() 437void Bu::Socket::setAddress()
424{ 438{
425 struct sockaddr_in addr; 439 struct sockaddr_in addr;
426 socklen_t len = sizeof(addr); 440 socklen_t len = sizeof(addr);
427 addr.sin_family = AF_INET; 441 addr.sin_family = AF_INET;
428 // getsockname( nSocket, (sockaddr *)(&addr), &len ); 442 // getsockname( nSocket, (sockaddr *)(&addr), &len );
429 getpeername( nSocket, (sockaddr *)(&addr), &len ); 443 DYNLOAD getpeername( nSocket, (sockaddr *)(&addr), &len );
444#ifdef WIN32
445 DYNLOAD inet_ntoa( sAddress, addr.sin_addr );
446#else
430 char buf[150]; 447 char buf[150];
431 sprintf( buf, "%s", inet_ntoa( addr.sin_addr ) ); 448 sprintf( buf, "%s", inet_ntoa( addr.sin_addr ) );
432 sAddress = buf; 449 sAddress = buf;
450#endif
433} 451}
434 452
435Bu::FString Bu::Socket::getAddress() const 453Bu::FString Bu::Socket::getAddress() const