diff options
author | David <david@xagasoft.com> | 2008-10-27 16:07:50 +0000 |
---|---|---|
committer | David <david@xagasoft.com> | 2008-10-27 16:07:50 +0000 |
commit | 61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9 (patch) | |
tree | 530a0d86ca1043dbc04cd7513bc5dd65768a266d /src/socket.cpp | |
parent | f7e8658f2274044bb452492b1af7e2cd5f82082c (diff) | |
download | libbu++-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 'src/socket.cpp')
-rw-r--r-- | src/socket.cpp | 90 |
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 | ||
196 | size_t Bu::Socket::read( void *pBuf, size_t nBytes ) | 196 | size_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 | ||
250 | size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) | 255 | size_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 | |||
423 | void Bu::Socket::setAddress() | 437 | void 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 | ||
435 | Bu::FString Bu::Socket::getAddress() const | 453 | Bu::FString Bu::Socket::getAddress() const |