DataServer: Common/Socket.cpp Source File Main Page Modules Namespaces Classes Files Directories File List File Members Common Socket.cppGo to the documentation of this file. 00001 /*
00002 @file Socket.cpp
00003
00004 Cross platform sockets.
00005
00006 $Id: Socket.cpp 5544 2009-07-27 14:04:45Z ds $
00007 */
00008
00009 #include
00010
00011 #include
00012 #include
00013 #include
00014
00015 #include // malloc,free etc.
00016
00017 #ifndef _WIN32
00018 extern int h_errno;
00019 #include
00020 #endif
00021
00022 #ifndef MSG_NOSIGNAL
00023 #define MSG_NOSIGNAL 0
00024 #endif
00025
00026 // The maximum possible packet size is 256 KB on most Linux platforms.
00027 // However, for proper LAN performance it is not advisable to send
00028 // such "large" packets, see, for example:
00029 // http://fasterdata.es.net/TCP-tuning/
00030 // We send data in chunks of 128 KB.
00031 #define MAX_PACKET_SIZE 131072
00032 //#define MAX_PACKET_SIZE 65536
00033
00034 /******************************************************************************/
00035
00036 Socket::Socket() : m_pDataBuffer(NULL), m_iDataBufferSize(0),
00037 m_iMaxPacketSize(MAX_PACKET_SIZE)
00038 {
00039 m_nBlocking = 0;
00040 m_pClientAddress = (struct sockaddr_in*)malloc(
00041 sizeof( struct sockaddr_in ) );
00042 m_nClientAddrStructLen = sizeof( struct sockaddr_in );
00043 m_nSocketFd = -1;
00044 }
00045
00046 /******************************************************************************/
00047
00048 Socket::Socket( int nPort ) : m_pDataBuffer(0), m_iDataBufferSize(0),
00049 m_iMaxPacketSize(MAX_PACKET_SIZE)
00050 {
00051 m_nPort = nPort;
00052 m_nBlocking = 0;
00053
00054 SocketsInit();
00055
00056 if( (m_nSocketFd = socket(AF_INET, SOCK_STREAM, 0 ) ) == -1 )
00057 {
00058 SYSTEM_ERROR("socket()");
00059 }
00060
00061 //
00062 // so that bind works
00063 m_pClientAddress = (struct sockaddr_in*)malloc(
00064 sizeof( struct sockaddr_in ) );
00065 m_pClientAddress->sin_family = AF_INET;
00066 m_pClientAddress->sin_addr.s_addr = htonl( INADDR_ANY );
00067 m_pClientAddress->sin_port = htons( nPort );
00068 }
00069
00070 /******************************************************************************/
00071
00072 Socket::~Socket()
00073 {
00074 free( m_pClientAddress );
00075 #ifdef WINDOWS_NT
00076 closesocket( m_nSocketFd );
00077 #else
00078 close( m_nSocketFd );
00079 #endif
00080 if(m_pDataBuffer!=NULL)
00081 delete[] m_pDataBuffer;
00082 m_pDataBuffer = NULL;
00083 }
00084
00085 /******************************************************************************/
00086
00087 bool Socket::SocketsInit()
00088 {
00089
00090 #ifdef _WIN32
00091 WORD wVersionRequested;
00092 WSADATA wsaData;
00093 int err;
00094
00095 wVersionRequested = MAKEWORD( 2, 2 );
00096
00097 err = WSAStartup( wVersionRequested, &wsaData );
00098 if ( err != 0 ) {
00099 /* Tell the user that we could not find a usable */
00100 /* WinSock DLL. */
00101
00102 printf("failed socket init\n");
00103 return false;
00104 }
00105
00106 /* Confirm that the WinSock DLL supports 2.2.*/
00107 /* Note that if the DLL supports versions greater */
00108 /* than 2.2 in addition to 2.2, it will still return */
00109 /* 2.2 in wVersion since that is the version we */
00110 /* requested. */
00111
00112 if ( LOBYTE( wsaData.wVersion ) != 2 ||
00113 HIBYTE( wsaData.wVersion ) != 2 ) {
00114 /* Tell the user that we could not find a usable */
00115 /* WinSock DLL.
00116 */
00117
00118 printf("failed socket init\n");
00119
00120 WSACleanup( );
00121 return false;
00122 }
00123 #endif
00124 return true;
00125 }
00126
00127 /******************************************************************************/
00128
00129 bool Socket::Connect( const std::string &sHostname )
00130 {
00131 struct sockaddr_in serverAddress;
00132
00133 serverAddress.sin_family = AF_INET;
00134 serverAddress.sin_port = htons( m_nPort );
00135
00136 // Resolve the IP address of the given host name
00137 std::string sHost( sHostname );
00138
00139 // TODO: there are newer functions that simplify all this...
00140 if( sHost.find_first_not_of("0123456789. ")!=std::string::npos )
00141 {
00142 // Store the IP address and socket port number
00143 struct hostent *pHost;
00144 struct in_addr *pAddr;
00145 if( (pHost = gethostbyname( sHostname.c_str() )) == NULL )
00146 {
00147 SYSTEM_ERROR("gethostbyname()");
00148 return(false);
00149 }
00150 pAddr = (struct in_addr*)pHost->h_addr;
00151 serverAddress.sin_addr.s_addr = inet_addr( inet_ntoa( *pAddr ) );
00152 if( serverAddress.sin_addr.s_addr == INADDR_NONE)
00153 {
00154 SYSTEM_ERROR("inet_addr()" );
00155 return(false);
00156 }
00157 }
00158 else
00159 {
00160 serverAddress.sin_addr.s_addr = inet_addr( sHostname.c_str() );
00161 if( serverAddress.sin_addr.s_addr == INADDR_NONE)
00162 {
00163 SYSTEM_ERROR("inet_addr()" );
00164 return(false);
00165 }
00166 }
00167 // Connect to the given address
00168 if( connect( m_nSocketFd, (struct sockaddr *)&serverAddress,
00169 sizeof(serverAddress) ) == -1 )
00170 {
00171 SYSTEM_ERROR("connect() to %s:%d.", sHostname.c_str(), m_nPort );
00172 return(false);
00173 }
00174 return(true);
00175 }
00176
00177 /******************************************************************************/
00178
00179 std::string Socket::ClientName()
00180 {
00181 if( m_sClientHostname.empty() )
00182 {
00183 socklen_t len;
00184 struct sockaddr_in sin;
00185 struct hostent *pHost=NULL;
00186 len = sizeof(sin);
00187 if( getpeername( m_nSocketFd, (struct sockaddr *) &sin, &len) < 0)
00188 {
00189 SYSTEM_ERROR("getpeername()");
00190 }
00191 else
00192 {
00193 if( (pHost = gethostbyaddr( (char *)&sin.sin_addr,
00194 sizeof(sin.sin_addr), AF_INET)) == NULL)
00195 {
00196 SYSTEM_ERROR("gethostbyaddr()");
00197 }
00198 // Store the host name
00199 m_sClientHostname = pHost->h_name;
00200 }
00201 }
00202 return m_sClientHostname;
00203 }
00204
00205 /******************************************************************************/
00206
00207 Socket *Socket::AcceptWithTimeout( double dTimeout )
00208 {
00209 // get a new socket object
00210 Socket *pSocket = new Socket;
00211 pSocket->m_nSocketFd = -1;
00212
00213 printf("accepting on fd %d, port %d\n", m_nSocketFd, m_nPort );
00214
00215 // wait a short bit for connections (listen socket is non-blocking!)
00216 double tic = MOOSTime();
00217 double delay = 0.5; // what half second at most
00218 while( MOOSTime() - tic < delay && pSocket->GetSocketFd() == -1)
00219 {
00220 // Accepts a new client connection and stores its socket file descriptor
00221 if( ( pSocket->m_nSocketFd = accept(
00222 m_nSocketFd,
00223 (struct sockaddr*)pSocket->m_pClientAddress,
00224 (socklen_t*)&pSocket->m_nClientAddrStructLen ) )== -1 )
00225 {
00226
00227 #ifdef _WIN32
00228 int eCode = WSAEWOULDBLOCK;
00229 #else
00230 int eCode = EWOULDBLOCK;
00231 #endif
00232 if( errno == eCode )
00233 {
00234 // ok just keep trying
00235 printf("would block\n");
00236 }
00237 else
00238 {
00239 SYSTEM_ERROR("accept()");
00240 }
00241 }
00242 else
00243 {
00244 PrintMsg(5,"Socket fd created by accept\n");
00245 }
00246 }
00247 if( MOOSTime() - tic > delay && pSocket->GetSocketFd() == -1 )
00248 {
00249 SYSTEM_ERROR("Timeout waiting for client to connect.");
00250 return NULL;
00251 }
00252
00253 struct hostent *pHost;
00254 if( (pHost = gethostbyaddr(
00255 (char *)&pSocket->m_pClientAddress->sin_addr,
00256 sizeof(pSocket->m_pClientAddress->sin_addr),
00257 AF_INET)) == NULL)
00258 {
00259 SYSTEM_ERROR("gethostbyaddr()");
00260 }
00261
00262 // Store the host name
00263 m_sClientHostname = pHost->h_name;
00264 return pSocket;
00265 }
00266
00267 /******************************************************************************/
00268
00269 Socket *Socket::Accept()
00270 {
00271 // get a new socket object
00272 Socket *pSocket = new Socket;
00273 pSocket->m_nSocketFd = -1;
00274
00275 //printf("accepting on fd %d, port %d\n", m_nSocketFd, m_nPort );
00276
00277 // Accepts a new client connection and stores its socket file descriptor
00278 if( ( pSocket->m_nSocketFd = accept(
00279 m_nSocketFd,
00280 (struct sockaddr *)pSocket->m_pClientAddress,
00281 (socklen_t*)&pSocket->m_nClientAddrStructLen) ) == -1 )
00282 {
00283 PrintMsg(4,"Socket::Accept() - accept()\n");
00284 //SYSTEM_ERROR("accept()");
00285 return(NULL);
00286 }
00287 struct hostent *pHost;
00288 if( (pHost = gethostbyaddr(
00289 (char *)&pSocket->m_pClientAddress->sin_addr,
00290 sizeof(pSocket->m_pClientAddress->sin_addr),
00291 AF_INET)) == NULL)
00292 {
00293 PrintMsg(4,"Socket::Accept() - gethostbyaddr()\n");
00294 //SYSTEM_ERROR("gethostbyaddr()");
00295 return(NULL);
00296 }
00297
00298 // Store the host name
00299 pSocket->m_sClientHostname = pHost->h_name;
00300 return(pSocket);
00301 }
00302
00303 /******************************************************************************/
00304
00305 void Socket::Listen( int nNumPorts )
00306 {
00307 // Incoming connections are listened for
00308 if( listen( m_nSocketFd, nNumPorts ) == -1 )
00309 {
00310 SYSTEM_ERROR("Socket::Listen() failed\n");
00311 }
00312 }
00313
00314 /******************************************************************************/
00315
00316 bool Socket::HasData()
00317 {
00318 fd_set fdReadSet;
00319 FD_ZERO(&fdReadSet);
00320 FD_SET(m_nSocketFd,&fdReadSet);
00321 struct timeval tTimeout={0};
00322 //if( select(range + 1, &fdReadSet, &fdWriteSet, &errorSet, (timeOut >= 0 ? &timev : NULL));
00323 if( select(m_nSocketFd+1,&fdReadSet,0,0,&tTimeout)<1 )
00324 return(false);
00325 if( FD_ISSET(m_nSocketFd,&fdReadSet)!=0 )
00326 return(true);
00327 return(false);
00328 // The following doesn't quite do the trick, and also is
00329 // supposed to be Linux-only - would have been nice though ;-)
00330 #if 0
00331 pollfd tPollData={0};
00332 tPollData.fd = m_nSocketFd;
00333 /* requested events */
00334 tPollData.events = POLLIN;
00335 int iTimeout = 0, r; /* milliseconds, negative value = no timeout */
00336 if( poll(&tPollData,1,iTimeout)>0 )
00337 {
00338 /* returned events are stored in tPollData.revents */
00339 if( tPollData.revents & POLLIN )
00340 {
00341 return(true);
00342 }
00343 }
00344 return(false);
00345 #endif
00346 }
00347
00348 /******************************************************************************/
00349
00350 void *Socket::ReceiveMessageWithHeader(
00351 int &iNumOfBytesRead, double dfTimeoutInSecs )
00352 {
00353 iNumOfBytesRead = 0;
00354 // If no timeout is specified the following read will block
00355 // until the "expected" data has been read.
00356 int iReceiveOption = MSG_WAITALL;
00357 bool bReadValid = true;
00358 if( dfTimeoutInSecs > 0.0 )
00359 {
00360 bReadValid = false;
00361 // The socket file descriptor set is cleared and the socket file descriptor
00362 // contained within tcpSocket is added to the file descriptor set.
00363 fd_set fdset; // Set of "watched" file descriptors
00364 FD_ZERO(&fdset);
00365 FD_SET( (unsigned int)m_nSocketFd, &fdset );
00366
00367 // This has to be here, within the loop as Linux actually writes over the
00368 // timeout structure on completion of select (now that was a hard bug to
00369 // find)
00370 struct timeval timeout; // The timeout value for the select system call
00371 timeout.tv_sec = (int)dfTimeoutInSecs;
00372 timeout.tv_usec = (int)(1e6*(dfTimeoutInSecs-timeout.tv_sec));
00373
00374 // A select is setup to return when data is available on the socket for
00375 // reading. If data is not available after timeout seconds, select returns
00376 // with a value of 0. If data is available on the socket, the select
00377 // returns and data can be retrieved off the socket.
00378 int nSelectRet = select( GetSocketFd() + 1, &fdset, NULL, NULL, &timeout );
00379 if( (nSelectRet==-1) || (nSelectRet==0) )
00380 {
00381 // Nothing to do. Note nothing will be read.
00382 PrintMsg(3,"Socket::ReceiveMessageWithHeader - Timeout or select()-failure...\n");
00383 }
00384 else if( FD_ISSET( m_nSocketFd, &fdset) != 0 )
00385 {
00386 bReadValid = true;
00387 }
00388 }
00389 if(bReadValid)
00390 {
00391 int iTmpNumOfBytes=0;
00392 #ifdef WINDOWS_NT
00393 // 1. Read the header - the number of bytes.
00394
00395 if( ReceiveMessageAll(&iTmpNumOfBytes,4)!=4 )
00396 {
00397 SYSTEM_ERROR("Failed to receive message header on socket.\n");
00398 return(NULL);
00399 }
00400 // 2. Make sure we have a buffer that is large enough.
00401 if( (m_pDataBuffer==NULL) || (m_iDataBufferSizem_iMaxPacketSize )
00473 {
00474 iTmpNumOfBytesToRead = m_iMaxPacketSize;
00475 }
00476 if( recv(m_nSocketFd,pTmp,iTmpNumOfBytesToRead,iReceiveOption)!=iTmpNumOfBytesToRead )
00477 {
00478 iNumOfBytesRead += iTmpNumOfBytesToRead;
00479 break;
00480 }
00481 iNumOfBytesRead += iTmpNumOfBytesToRead;
00482 pTmp += iTmpNumOfBytesToRead;
00483 }
00484 }
00485 if( iNumOfBytesRead==iTmpNumOfBytes )
00486 {
00487 iNumOfBytesRead = iTmpNumOfBytes;
00488 return(m_pDataBuffer);
00489 }
00490 }
00491 return(NULL);
00492 }
00493
00494 /******************************************************************************/
00495
00496 int Socket::SendMessageWithHeader( void *pMessage, int iNumOfBytesToWrite )
00497 {
00498 // 1. Send 4 bytes (an integer) containing the number
00499 // of bytes of the rest of the message
00500 int iOptions = MSG_NOSIGNAL;
00501 //fprintf(stderr,"\nbefore writing header, %d bytes\n",iNumOfBytesToWrite);
00502 if( send(m_nSocketFd,(char*)&iNumOfBytesToWrite,4,iOptions)!=4 )
00503 {
00504 PrintMsg(5,"Failed to send message header on socket.\n");
00505 return(0);
00506 }
00507 //fprintf(stderr,"\nafter writing header\n");
00508
00509 // 2. Send the given message to the connected host
00510 // The maximum possible packet size is 256 KB on most Linux platforms.
00511 // However, for proper LAN performance it is not advisable to send
00512 // such "large" packets, see, for example:
00513 // http://fasterdata.es.net/TCP-tuning/
00514 // We send data in chunks of 128 KB.
00515 int iNumOfBytesWritten = 0;
00516 if( iNumOfBytesToWritem_iMaxPacketSize )
00530 {
00531 iTmpNumOfBytesToWrite = m_iMaxPacketSize;
00532 }
00533 if( send(m_nSocketFd,pTmp,iTmpNumOfBytesToWrite,iOptions) != iTmpNumOfBytesToWrite )
00534 {
00535 iNumOfBytesWritten += iTmpNumOfBytesToWrite;
00536 break;
00537 }
00538 iNumOfBytesWritten += iTmpNumOfBytesToWrite;
00539 pTmp += iTmpNumOfBytesToWrite;
00540 }
00541 }
00542 if( iNumOfBytesWritten!=iNumOfBytesToWrite )
00543 {
00544 PrintMsg(5,"Failed to send the given message on socket.\n");
00545 return(0);
00546 }
00547 return(iNumOfBytesWritten);
00548 }
00549
00550 /******************************************************************************/
00551
00552 int Socket::SendMessage( void *pMessage, int nMessageSize )
00553 {
00554 int nNumBytes; // Stores the number of bytes sent
00555 // Sends the message to the connected host
00556 nNumBytes = send( m_nSocketFd, (char*)pMessage, nMessageSize, 0 );
00557 if( nNumBytes == -1 )
00558 {
00559 PrintMsg(3,"\nError: Socket::SendMessage() failed");
00560 }
00561 return nNumBytes;
00562 }
00563
00564 /******************************************************************************/
00565 #ifdef WINDOWS_NT
00566 int Socket::ReceiveMessageAll(
00567 void *pMessage,
00568 int nMessageSize
00569 )
00570 {
00571 int nNumBytes = 0; // The number of bytes received
00572 int nCurrentSize = nMessageSize; // The number of bytes wanted toreceive
00573 int nOffsetSize = 0; // The number of bytes currentlyreceived
00574
00575 // While the number of bytes received is less than the number
00576 // requestedcontinue to retrieve more data
00577 while (nNumBytes < nCurrentSize){
00578 // The socket message is received and stored within the mesageoffset by
00579 // the offset number of bytes
00580 nNumBytes = recv( m_nSocketFd,
00581 (char*)pMessage + nOffsetSize, nCurrentSize, 0);
00582 if (nNumBytes < 0){
00583 // If the reason for failure is a client disconnect, an exception
00584 // isnot thrown. The number of bytes returned is 0
00585 if (WSAGetLastError() == WSAECONNRESET){
00586 return 0;
00587 }
00588 return nNumBytes;
00589 }
00590 else if (nNumBytes == 0){
00591 return nNumBytes;
00592 }
00593
00594 // If the total number of bytes requested are not returned, the offset
00595 // is adjusted and the number of bytes left to receive is also adjusted
00596 else if (nNumBytes < nCurrentSize){
00597 nOffsetSize += nNumBytes;
00598 nCurrentSize = nCurrentSize - nNumBytes;
00599 nNumBytes = 0;
00600 }
00601 }
00602
00603 return nMessageSize;
00604 }
00605 #endif
00606
00607 /******************************************************************************/
00608 int Socket::ReceiveMessage(
00609 void *pMessage,
00610 int nMessageSize,
00611 int nOption
00612 )
00613 {
00614 #ifdef WINDOWS_NT
00615 if (nOption == MSG_WAITALL){
00616 // If the option is MSG_WAITALL and this is a WINDOW machine call
00617 // ReceiveMessageAll to process it
00618 return ReceiveMessageAll( pMessage, nMessageSize);
00619 }
00620 #endif
00621
00622 // Receives a TCP socket message. The number of bytes received isreturned
00623 // note on recv: If no messages are available to be received and the peer
00624 // has performed an orderly shutdown, the value 0 is returned.
00625 return recv( m_nSocketFd, (char*)pMessage, nMessageSize, nOption);
00626 }
00627
00628 /******************************************************************************/
00629 void Socket::BindSocket()
00630 {
00631 m_nClientAddrStructLen = sizeof( struct sockaddr_in );
00632 // Bind the socket to the given address and port number
00633 if( bind( m_nSocketFd, (struct sockaddr *)m_pClientAddress,
00634 m_nClientAddrStructLen ) == -1 )
00635 {
00636 SYSTEM_ERROR("bind() failed\n");
00637 }
00638 }
00639
00640 /******************************************************************************/
00641 // returns number of bytes read. bPeerDown is set if the peer has shutdown.
00642 int Socket::ReadMessageWithTimeout(
00643 void *pMessage,
00644 int nMessageSize,
00645 double dfTimeOut,
00646 bool &bPeerDown,
00647 int nOption
00648 )
00649 {
00650 int nNumBytes = 0;
00651 struct timeval timeout; // The timeout value for the select system call
00652 fd_set fdset; // Set of "watched" file descriptors
00653
00654 bPeerDown = false;
00655
00656 // The socket file descriptor set is cleared and the socket file descriptor
00657 // contained within tcpSocket is added to the file descriptor set.
00658 FD_ZERO(&fdset);
00659 FD_SET( (unsigned int)m_nSocketFd, &fdset );
00660
00661 // This has to be here, within the loop as Linux actually writes over the
00662 // timeout structure on completion of select (now that was a hard bug to
00663 // find)
00664 timeout.tv_sec = (int)dfTimeOut;
00665 timeout.tv_usec = (int)(1e6*(dfTimeOut-timeout.tv_sec));
00666
00667 // A select is setup to return when data is available on the socket for
00668 // reading. If data is not available after timeout seconds, select returns
00669 // with a value of 0. If data is available on the socket, the select
00670 // returns and data can be retrieved off the socket.
00671 int nSelectRet = select( GetSocketFd() + 1,
00672 &fdset,
00673 NULL,
00674 NULL,
00675 &timeout );
00676
00677 // If select returns a -1, then it failed and the thread exits.
00678 if( nSelectRet == -1 ){
00679 nNumBytes=-1;
00680 } else if( nSelectRet == 0 ){
00681 // timeout...nothing to read
00682 nNumBytes = 0;
00683 } else {
00684 if (FD_ISSET( m_nSocketFd, &fdset) != 0){
00685 // something to read:
00686 nNumBytes = ReceiveMessage( pMessage, nMessageSize, nOption );
00687 // Problem: if the peer has shutdwon recv will return 0, in which
00688 // case won't be able to tell if there is nothing to read or the
00689 // peer is down... FIXED: added bClientDown output param
00690 if( nNumBytes == 0 ){
00691 bPeerDown = true;
00692 }
00693 }
00694 }
00695
00696 // zero socket set
00697 FD_ZERO(&fdset);
00698
00699 return nNumBytes;
00700 }
00701
00702 /******************************************************************************/
00703 double Socket::GetReadTime()
00704 {
00705 return m_dfLastRead;
00706 }
00707
00708 /******************************************************************************/
00709 void Socket::SetReadTime(
00710 double dfTime
00711 )
00712 {
00713 m_dfLastRead = dfTime;
00714 }
00715
00716 /******************************************************************************/
00717 short int Socket::GetSocketFd()
00718 {
00719 return m_nSocketFd;
00720 }
00721
00722 /******************************************************************************/
00723 int Socket::GetSocketBlocking()
00724 {
00725 return m_nBlocking;
00726 }
00727
00728 /******************************************************************************/
00729 void Socket::SetTcpNoDelay(
00730 int nToggle
00731 )
00732 {
00733 if( setsockopt( m_nSocketFd, IPPROTO_TCP, TCP_NODELAY,
00734 (char*)&nToggle, sizeof(nToggle) ) < 0){
00735 SYSTEM_ERROR("setsockopt()");
00736 }
00737 }
00738
00739 /******************************************************************************/
00740 void Socket::SetDebug(
00741 int nToggle
00742 )
00743 {
00744 if( setsockopt( m_nSocketFd, SOL_SOCKET, SO_DEBUG,
00745 (char *)&nToggle, sizeof(nToggle)) == -1 ){
00746 SYSTEM_ERROR("setsockopt()");
00747 }
00748 }
00749
00750 /******************************************************************************/
00751 void Socket::SetBroadcast(
00752 int nToggle
00753 )
00754 {
00755 if( setsockopt(m_nSocketFd, SOL_SOCKET, SO_BROADCAST,
00756 (char *)&nToggle, sizeof(nToggle)) == -1 ){
00757 SYSTEM_ERROR("setsockopt()");
00758 }
00759 }
00760
00761 /******************************************************************************/
00762 void Socket::SetReuseAddr(
00763 int nToggle
00764 )
00765 {
00766 if( setsockopt( m_nSocketFd, SOL_SOCKET, SO_REUSEADDR,
00767 (char *)&nToggle, sizeof(nToggle)) == -1 ){
00768 SYSTEM_ERROR("setsockopt()");
00769 }
00770 }
00771
00772 /******************************************************************************/
00773 void Socket::SetKeepAlive(
00774 int nToggle
00775 )
00776 {
00777 if( setsockopt(m_nSocketFd, SOL_SOCKET, SO_KEEPALIVE,
00778 (char *)&nToggle, sizeof(nToggle)) == -1 ){
00779 SYSTEM_ERROR("setsockopt()");
00780 }
00781 }
00782
00783 /******************************************************************************/
00784
00785 void Socket::SetLinger( struct linger lingerOption )
00786 {
00787 if( setsockopt(m_nSocketFd, SOL_SOCKET, SO_LINGER,
00788 (char *)&lingerOption, sizeof(struct linger)) == -1)
00789 {
00790 SYSTEM_ERROR("setsockopt()");
00791 }
00792 }
00793
00794 /******************************************************************************/
00795
00796 void Socket::SetSendBufSize( int nSendBufSize )
00797 {
00798 if( setsockopt(m_nSocketFd, SOL_SOCKET, SO_SNDBUF,
00799 (char *)&nSendBufSize, sizeof(nSendBufSize)) == -1)
00800 {
00801 SYSTEM_ERROR("setsockopt()");
00802 }
00803 }
00804
00805 /******************************************************************************/
00806
00807 void Socket::SetReceiveBufSize( int nReceiveBufSize )
00808 {
00809 if( setsockopt( m_nSocketFd, SOL_SOCKET, SO_SNDBUF,
00810 (char *)&nReceiveBufSize, sizeof(nReceiveBufSize)) == -1)
00811 {
00812 SYSTEM_ERROR("setsockopt()");
00813 }
00814 }
00815
00816 /******************************************************************************/
00817
00818 bool Socket::SetSocketBlocking( int nToggle )
00819 {
00820 if( nToggle )
00821 {
00822 if( m_nBlocking )
00823 {
00824 return(true);
00825 }
00826 else
00827 {
00828 m_nBlocking = 1;
00829 // Socket blocking is turned ON
00830 #ifdef WINDOWS_NT
00831 if( ioctlsocket( m_nSocketFd, FIONBIO,
00832 (unsigned long *)&m_nBlocking) == -1 )
00833 {
00834 SYSTEM_ERROR("setsockopt()");
00835 return(false);
00836 }
00837 #elif UNIX
00838 if( ioctl(m_nSocketFd, FIONBIO, (char *)&m_nBlocking) == -1 )
00839 {
00840 SYSTEM_ERROR("setsockopt()");
00841 return(false);
00842 }
00843 #endif
00844 }
00845 }
00846 else
00847 {
00848 if( !m_nBlocking )
00849 {
00850 return(false);
00851 }
00852 else
00853 {
00854 m_nBlocking = 0;
00855 // Socket blocking is turned off
00856 #ifdef WINDOWS_NT
00857 if( ioctlsocket( m_nSocketFd, FIONBIO,
00858 (unsigned long *)&m_nBlocking) == -1 )
00859 {
00860 SYSTEM_ERROR("setsockopt()");
00861 return(false);
00862 }
00863 #else
00864 if (ioctl(m_nSocketFd, FIONBIO, (char *)&m_nBlocking) == -1)
00865 {
00866
00867 SYSTEM_ERROR("setsockopt()");
00868 return(false);
00869 }
00870 #endif
00871 }
00872 }
00873 return(true);
00874 }
00875
00876 /******************************************************************************/
00877
00878 int Socket::GetDebug()
00879 {
00880 int nGetOption;
00881 int nOptionLen = sizeof(nGetOption);
00882
00883 if( getsockopt( m_nSocketFd, SOL_SOCKET, SO_DEBUG,
00884 (char *)&nGetOption, (socklen_t*) &nOptionLen) == -1 )
00885 {
00886 SYSTEM_ERROR("getsockopt()");
00887 return(-1);
00888 }
00889 return nGetOption;
00890 }
00891
00892 /******************************************************************************/
00893 int Socket::GetBroadcast()
00894 {
00895 int nGetOption;
00896 int nOptionLen = sizeof(nGetOption);
00897
00898 if( getsockopt( m_nSocketFd, SOL_SOCKET, SO_BROADCAST,
00899 (char *)&nGetOption, (socklen_t*) &nOptionLen) == -1){
00900 SYSTEM_ERROR("getsockopt()");
00901 return(-1);
00902 }
00903 return nGetOption;
00904 }
00905
00906 /******************************************************************************/
00907 int Socket::GetReuseAddr()
00908 {
00909 int nGetOption;
00910 int nOptionLen = sizeof(nGetOption);
00911
00912 if( getsockopt(m_nSocketFd, SOL_SOCKET, SO_REUSEADDR,
00913 (char *)&nGetOption, (socklen_t*)&nOptionLen) == -1 ){
00914 SYSTEM_ERROR("setsockopt()");
00915 return(-1);
00916 }
00917 return nGetOption;
00918 }
00919
00920 /******************************************************************************/
00921 int Socket::GetKeepAlive()
00922 {
00923 int nGetOption;
00924 int nOptionLen = sizeof(nGetOption);
00925
00926 if( getsockopt( m_nSocketFd, SOL_SOCKET, SO_KEEPALIVE,
00927 (char *)&nGetOption, (socklen_t*) &nOptionLen) == -1){
00928 SYSTEM_ERROR("setsockopt()");
00929 return(-1);
00930 }
00931 return nGetOption;
00932 }
00933
00934 /******************************************************************************/
00935 void Socket::GetLinger(struct linger &lingerOption)
00936 {
00937 int nOptionLen = sizeof(struct linger);
00938
00939 if( getsockopt( m_nSocketFd, SOL_SOCKET, SO_LINGER,
00940 (char *)&lingerOption, (socklen_t*)&nOptionLen) == -1 ){
00941 SYSTEM_ERROR("getsockopt()");
00942 }
00943 }
00944
00945 /******************************************************************************/
00946 int Socket::GetSendBufSize()
00947 {
00948 int nSendBufSize;
00949 int nOptionLen = sizeof(nSendBufSize);
00950
00951 if( getsockopt( m_nSocketFd, SOL_SOCKET, SO_SNDBUF,
00952 (char *)&nSendBufSize, (socklen_t*) &nOptionLen ) == -1){
00953 SYSTEM_ERROR("getsockopt()");
00954 return(-1);
00955 }
00956 return nSendBufSize;
00957 }
00958
00959 /******************************************************************************/
00960 int Socket::GetReceiveBufSize()
00961 {
00962 int nRcvBufSize;
00963 int nOptionLen = sizeof( nRcvBufSize );
00964
00965 if( getsockopt(m_nSocketFd, SOL_SOCKET, SO_RCVBUF,
00966 (char *)&nRcvBufSize, (socklen_t*) &nOptionLen ) == -1) {
00967 SYSTEM_ERROR("getsockopt()");
00968 return(-1);
00969 }
00970 return nRcvBufSize;
00971 }
00972
00973 /******************************************************************************/
00974 void Socket::SetReceiveTimeOut(
00975 int nTimeOut
00976 )
00977 {
00978 if( setsockopt( m_nSocketFd, SOL_SOCKET, SO_RCVTIMEO,
00979 (char *)&nTimeOut, sizeof(nTimeOut)) == -1) {
00980 SYSTEM_ERROR("setsockopt()");
00981 }
00982 }
00983
Generated on Mon Nov 30 09:54:57 2009 for DataServer by 1.6.1