aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/socket.cpp77
1 files changed, 73 insertions, 4 deletions
diff --git a/src/socket.cpp b/src/socket.cpp
index 531d8ac..1e9a2f9 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -11,16 +11,21 @@
11#include <stdlib.h> 11#include <stdlib.h>
12#include <unistd.h> 12#include <unistd.h>
13#include <sys/types.h> 13#include <sys/types.h>
14#include <sys/socket.h>
15#include <sys/time.h> 14#include <sys/time.h>
16#include <netinet/in.h>
17#include <netdb.h>
18#include <arpa/inet.h>
19#include <errno.h> 15#include <errno.h>
20#include <fcntl.h> 16#include <fcntl.h>
21#include "socket.h" 17#include "socket.h"
22#include "osx_compatibility.h" 18#include "osx_compatibility.h"
23 19
20#ifndef WIN32
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <netdb.h>
24 #include <arpa/inet.h>
25#else
26 #include <Winsock2.h>
27#endif
28
24#define RBS (1024*2) 29#define RBS (1024*2)
25 30
26namespace Bu { subExceptionDef( SocketException ) } 31namespace Bu { subExceptionDef( SocketException ) }
@@ -46,6 +51,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout )
46 } 51 }
47 52
48 // These lines set the socket to non-blocking, a good thing? 53 // These lines set the socket to non-blocking, a good thing?
54#ifndef WIN32
49 int flags; 55 int flags;
50 flags = fcntl(nSocket, F_GETFL, 0); 56 flags = fcntl(nSocket, F_GETFL, 0);
51 flags |= O_NONBLOCK; 57 flags |= O_NONBLOCK;
@@ -53,6 +59,16 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout )
53 { 59 {
54 throw Bu::SocketException("Couldn't set socket options.\n"); 60 throw Bu::SocketException("Couldn't set socket options.\n");
55 } 61 }
62#else
63 //-------------------------
64 // Set the socket I/O mode: In this case FIONBIO
65 // enables or disables the blocking mode for the
66 // socket based on the numerical value of iMode.
67 // If iMode = 0, blocking is enabled;
68 // If iMode != 0, non-blocking mode is enabled.
69 u_long iMode = 1;
70 ioctlsocket(nSocket, FIONBIO, &iMode);
71#endif
56 72
57 /* Connect to the server. */ 73 /* Connect to the server. */
58 //printf("Resolving hostname (%s)...\n", sAddr ); 74 //printf("Resolving hostname (%s)...\n", sAddr );
@@ -115,7 +131,9 @@ void Bu::Socket::close()
115{ 131{
116 if( bActive ) 132 if( bActive )
117 { 133 {
134#ifndef WIN32
118 fsync( nSocket ); 135 fsync( nSocket );
136#endif
119 ::close( nSocket ); 137 ::close( nSocket );
120 } 138 }
121 bActive = false; 139 bActive = false;
@@ -176,7 +194,11 @@ void Bu::Socket::read()
176 194
177size_t Bu::Socket::read( void *pBuf, size_t nBytes ) 195size_t Bu::Socket::read( void *pBuf, size_t nBytes )
178{ 196{
197#ifndef WIN32
179 int nRead = TEMP_FAILURE_RETRY( ::read( nSocket, pBuf, nBytes ) ); 198 int nRead = TEMP_FAILURE_RETRY( ::read( nSocket, pBuf, nBytes ) );
199#else
200 int nRead = ::read( nSocket, pBuf, nBytes );
201#endif
180 if( nRead < 0 ) 202 if( nRead < 0 )
181 { 203 {
182 throw SocketException( SocketException::cRead, strerror(errno) ); 204 throw SocketException( SocketException::cRead, strerror(errno) );
@@ -194,9 +216,15 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes,
194 FD_ZERO(&rfds); 216 FD_ZERO(&rfds);
195 FD_SET(nSocket, &rfds); 217 FD_SET(nSocket, &rfds);
196 218
219#ifndef WIN32
197 gettimeofday( &nt, NULL ); 220 gettimeofday( &nt, NULL );
198 nt.tv_sec += nSec; 221 nt.tv_sec += nSec;
199 nt.tv_usec += nUSec; 222 nt.tv_usec += nUSec;
223#else
224 DWORD dwStart = GetTickCount();
225 uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000));
226 DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver;
227#endif
200 228
201 for(;;) 229 for(;;)
202 { 230 {
@@ -206,18 +234,28 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes,
206 nRead += read( ((char *)pBuf)+nRead, nBytes-nRead ); 234 nRead += read( ((char *)pBuf)+nRead, nBytes-nRead );
207 if( nRead >= nBytes ) 235 if( nRead >= nBytes )
208 break; 236 break;
237#ifndef WIN32
209 gettimeofday( &ct, NULL ); 238 gettimeofday( &ct, NULL );
210 if( (ct.tv_sec > nt.tv_sec) || 239 if( (ct.tv_sec > nt.tv_sec) ||
211 (ct.tv_sec == nt.tv_sec && 240 (ct.tv_sec == nt.tv_sec &&
212 ct.tv_usec >= nt.tv_usec) ) 241 ct.tv_usec >= nt.tv_usec) )
213 break; 242 break;
243#else
244 DWORD dwNow = GetTickCount();
245 if( dwNow > dwEnd )
246 break;
247#endif
214 } 248 }
215 return nRead; 249 return nRead;
216} 250}
217 251
218size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) 252size_t Bu::Socket::write( const void *pBuf, size_t nBytes )
219{ 253{
254#ifndef WIN32
220 int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) ); 255 int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) );
256#else
257 int nWrote = ::write( nSocket, pBuf, nBytes );
258#endif
221 if( nWrote < 0 ) 259 if( nWrote < 0 )
222 { 260 {
223 if( errno == EAGAIN ) return 0; 261 if( errno == EAGAIN ) return 0;
@@ -235,9 +273,15 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32
235 FD_ZERO(&wfds); 273 FD_ZERO(&wfds);
236 FD_SET(nSocket, &wfds); 274 FD_SET(nSocket, &wfds);
237 275
276#ifndef WIN32
238 gettimeofday( &nt, NULL ); 277 gettimeofday( &nt, NULL );
239 nt.tv_sec += nSec; 278 nt.tv_sec += nSec;
240 nt.tv_usec += nUSec; 279 nt.tv_usec += nUSec;
280#else
281 DWORD dwStart = GetTickCount();
282 uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000));
283 DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver;
284#endif
241 285
242 for(;;) 286 for(;;)
243 { 287 {
@@ -247,11 +291,17 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32
247 nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote ); 291 nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote );
248 if( nWrote >= nBytes ) 292 if( nWrote >= nBytes )
249 break; 293 break;
294#ifndef WIN32
250 gettimeofday( &ct, NULL ); 295 gettimeofday( &ct, NULL );
251 if( (ct.tv_sec > nt.tv_sec) || 296 if( (ct.tv_sec > nt.tv_sec) ||
252 (ct.tv_sec == nt.tv_sec && 297 (ct.tv_sec == nt.tv_sec &&
253 ct.tv_usec >= nt.tv_usec) ) 298 ct.tv_usec >= nt.tv_usec) )
254 break; 299 break;
300#else
301 DWORD dwNow = GetTickCount();
302 if( dwNow > dwEnd )
303 break;
304#endif
255 } 305 }
256 return nWrote; 306 return nWrote;
257} 307}
@@ -337,6 +387,7 @@ bool Bu::Socket::isBlocking()
337 387
338void Bu::Socket::setBlocking( bool bBlocking ) 388void Bu::Socket::setBlocking( bool bBlocking )
339{ 389{
390#ifndef WIN32
340 if( bBlocking ) 391 if( bBlocking )
341 { 392 {
342 fcntl( nSocket, F_SETFL, fcntl( nSocket, F_GETFL, 0 ) & ~O_NONBLOCK ); 393 fcntl( nSocket, F_SETFL, fcntl( nSocket, F_GETFL, 0 ) & ~O_NONBLOCK );
@@ -345,6 +396,20 @@ void Bu::Socket::setBlocking( bool bBlocking )
345 { 396 {
346 fcntl( nSocket, F_SETFL, fcntl( nSocket, F_GETFL, 0 ) | O_NONBLOCK ); 397 fcntl( nSocket, F_SETFL, fcntl( nSocket, F_GETFL, 0 ) | O_NONBLOCK );
347 } 398 }
399#else
400 u_long iMode;
401 if( bBlocking )
402 iMode = 0;
403 else
404 iMode = 1;
405 //-------------------------
406 // Set the socket I/O mode: In this case FIONBIO
407 // enables or disables the blocking mode for the
408 // socket based on the numerical value of iMode.
409 // If iMode = 0, blocking is enabled;
410 // If iMode != 0, non-blocking mode is enabled.
411 ioctlsocket(nSocket, FIONBIO, &iMode);
412#endif
348} 413}
349 414
350void Bu::Socket::flush() 415void Bu::Socket::flush()
@@ -356,6 +421,10 @@ bool Bu::Socket::isOpen()
356 return bActive; 421 return bActive;
357} 422}
358 423
424#ifdef WIN32
425 typedef int socklen_t;
426#endif
427
359void Bu::Socket::setAddress() 428void Bu::Socket::setAddress()
360{ 429{
361 struct sockaddr_in addr; 430 struct sockaddr_in addr;