lugre_net.cpp

Go to the documentation of this file.
00001 // ****** ****** ****** input.cpp
00002 #include "lugre_prefix.h"
00003 #include "lugre_net.h"
00004 
00005 #include <errno.h>
00006 
00007 #ifdef WIN32
00008     #include <winsock2.h>
00009 #else
00010     #include <netdb.h>
00011     #include <sys/types.h>
00012     #include <netinet/in.h>
00013     #include <sys/socket.h>
00014     #include <arpa/inet.h>
00015 #endif
00016 
00017 #include <string.h> // char *strerror(int errnum);
00018 
00019 
00020 #ifdef WIN32
00021     #ifndef socklen_t
00022     #define socklen_t int
00023     #endif
00024 #endif
00025 
00026 
00027 
00028 namespace Lugre {
00029     
00030 fd_set  sSelectSet_Read;
00031 fd_set  sSelectSet_Write;
00032 fd_set  sSelectSet_Except;
00033 
00034 #define kConMinRecvSpace (1024*32)
00035 #define kConStartSpace (1024*32*2)
00036 
00037 #ifndef WIN32
00038 void closesocket(int socket){
00039     close(socket);
00040 }
00041 #endif
00042 
00043 
00044 #define kMaxUDPMsgLen       65507  // TODO : unhardcode this, should be in some header ?!?
00045 
00046 
00047 // ****** ****** ****** cNet
00048 
00049 cNet::cNet  () { PROFILE
00050     #ifdef WIN32
00051         WSADATA wsaData;
00052         WSAStartup( MAKEWORD( 2, 0 ), &wsaData );
00053     #endif
00054 }
00055 
00056 cNet::~cNet () { PROFILE
00057     #ifdef WIN32
00058         WSACleanup();
00059     #endif
00060 
00061     for (std::set<cNetListener*>::iterator  itor=mlListener.begin();itor!=mlListener.end(); ++itor) delete (*itor);
00062     for (std::set<cConnection*>::iterator   itor=mlCons.begin();    itor!=mlCons.end();     ++itor) delete (*itor);
00063     for (std::set<cConnection*>::iterator   itor=mlDeadCons.begin();itor!=mlDeadCons.end(); ++itor) delete (*itor);
00064     for (std::set<cConnection*>::iterator   itor=mlDyingCons.begin();itor!=mlDyingCons.end();   ++itor) delete (*itor);
00065 }
00066 
00067 void    cNet::Step  () { PROFILE
00068     // step listeners
00069     for (std::set<cNetListener*>::iterator itor=mlListener.begin();itor!=mlListener.end();++itor) (*itor)->Step();
00070 
00071     // step connections
00072     if (mlCons.size() > 0) {
00073 
00074         int res,mysocket,imax=0;
00075         timeval timeout;
00076         timeout.tv_sec = 0;
00077         timeout.tv_usec = 0;
00078 
00079         FD_ZERO(&sSelectSet_Read);
00080         FD_ZERO(&sSelectSet_Write);
00081         FD_ZERO(&sSelectSet_Except);
00082 
00083         for (std::set<cConnection*>::iterator itor=mlCons.begin(); itor!=mlCons.end(); ++itor) {
00084             mysocket = (*itor)->miSocket;
00085             if (mysocket != INVALID_SOCKET) {
00086                 if (imax < mysocket)
00087                     imax = mysocket;
00088                 FD_SET((unsigned int)mysocket,&sSelectSet_Read);
00089                 FD_SET((unsigned int)mysocket,&sSelectSet_Write);
00090                 FD_SET((unsigned int)mysocket,&sSelectSet_Except);
00091             }
00092         }
00093 
00094         res = select(imax+1,&sSelectSet_Read,&sSelectSet_Write,&sSelectSet_Except,&timeout);
00095 
00096         for (std::set<cConnection*>::iterator itor=mlCons.begin(); itor!=mlCons.end(); ++itor) if ((*itor)->miSocket != INVALID_SOCKET) {
00097             (*itor)->Step(  FD_ISSET((unsigned int)(*itor)->miSocket,&sSelectSet_Read) != 0,
00098                             FD_ISSET((unsigned int)(*itor)->miSocket,&sSelectSet_Write) != 0,
00099                             FD_ISSET((unsigned int)(*itor)->miSocket,&sSelectSet_Except) != 0 );
00100         }
00101     }
00102 
00103     for (std::set<cBroadcast*>::iterator itor=mlBroadCasts.begin();itor!=mlBroadCasts.end();++itor) (*itor)->Step();
00104 
00105     //move dying connections from the active ones to the dead cons
00106     for (std::set<cConnection*>::iterator itor=mlDyingCons.begin();itor!=mlDyingCons.end();++itor) {
00107             mlCons.erase(*itor);
00108             mlDeadCons.insert(*itor);
00109             for (std::set<cBroadcast*>::iterator itor2=mlBroadCasts.begin();itor2!=mlBroadCasts.end();++itor2)
00110                 (*itor2)->mlCons.erase(*itor);
00111     }
00112     mlDyingCons.clear();
00113 
00114 }
00115 
00116 
00117 const bool  cConnection::IsConnected() {
00118     return miSocket != INVALID_SOCKET;
00119 }
00120 
00121 
00124 unsigned int cNet::GetHostByName    (const char *szHost) { PROFILE
00125     assert(szHost);
00126     if (!szHost) return 0;
00127     // gethostbyname
00128     hostent*        h;
00129     h = gethostbyname(szHost);
00130     if(h){
00131         unsigned int res = *((uint32 *)h->h_addr);
00132         if (res == INADDR_NONE) return 0;
00133         return res;
00134     } else if(inet_addr(szHost) != INADDR_NONE){
00135         return inet_addr(szHost);
00136     } else {
00137         return 0;
00138     }
00139 }
00140 
00141 /*
00142 //Log('L',"%s -> %i.%i.%i.%i:%i\n",szHost,
00143 //      sAddr.sin_addr.s_net,   sAddr.sin_addr.s_host,
00144 //      sAddr.sin_addr.s_lh,    sAddr.sin_addr.s_impno,iPort);
00145 
00146 // winsock2.h
00147 // AF_INET : internetwork: UDP, TCP, etc.
00148 // AF_IPX : IPX protocols: IPX, SPX, etc.
00149 // AF_IPX AF_INET6 AF_NETBIOS AF_APPLETALK
00150 
00151 // SOCK_STREAM     // stream socket
00152 // SOCK_DGRAM      // datagram socket
00153 // SOCK_RAW        // raw-protocol interface
00154 // SOCK_RDM        // reliably-delivered message
00155 // SOCK_SEQPACKET  // sequenced packet stream
00156 
00157 // IPPROTO_IP    // dummy for IP
00158 // IPPROTO_TCP   // tcp
00159 // IPPROTO_UDP   // user datagram protocol
00160 // IPPROTO_RAW   // raw IP packet
00161 */
00162 
00165 int     cNet::ConnectSocket (uint32 iIP,const int iPort) { PROFILE
00166     if (iIP == 0) return INVALID_SOCKET;
00167     // resolving host
00168     sockaddr_in     sAddr;
00169     sAddr.sin_family = AF_INET;
00170     sAddr.sin_port = htons(iPort);
00171     sAddr.sin_addr.s_addr = iIP;
00172 
00173     // now connecting
00174 
00175     int     iSocket;
00176     iSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00177     //iSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_TCP);
00178     if (iSocket == INVALID_SOCKET) {
00179         printf("cNet::ConnectSocket : socket creation failed (port:%d)\n",iPort);
00180         return INVALID_SOCKET;
00181     }
00182     if (connect(iSocket,(const sockaddr*)&sAddr,sizeof(sAddr)) == SOCKET_ERROR) {
00183         printf("cNet::ConnectSocket : socket connect failed (port:%d)\n",iPort);
00184         return INVALID_SOCKET;
00185     }
00186 
00187     return iSocket;
00188 }
00189 
00190 bool        cNet::IsInvalidSocket   (const int iSocket) { return iSocket == INVALID_SOCKET; }
00191 void        cNet::CloseSocket       (const int iSocket) { closesocket(iSocket); }
00192 int         cNet::Send              (const int iSocket,const char* pBuffer,const int iBufferSize,const int iFlags) {
00193     return send(iSocket,pBuffer,iBufferSize,iFlags);
00194 }
00195 int         cNet::Recv              (const int iSocket,char* pBuffer,const int iBufferSize,const int iFlags) {
00196     return recv(iSocket,pBuffer,iBufferSize,iFlags);
00197 }
00198 
00200 cConnection*    cNet::Connect   (const char* szHost,const int iPort) { PROFILE
00201     uint32  iIP = GetHostByName(szHost);
00202     int     iSocket = ConnectSocket(iIP,iPort);
00203     if (iSocket == INVALID_SOCKET) {
00204         printf("cNet::Connect : ConnectSocket failed (%s:%d)\n",szHost,iPort);
00205         return 0;
00206     }
00207     return new cConnection(iSocket,szHost,iPort,iIP);
00208 }
00209 
00210 
00211 cNetListener*   cNet::Listen    (const int iPort) { PROFILE
00212     int     iListenSocket;
00213 
00214     // create socket
00215     iListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00216     if (iListenSocket == INVALID_SOCKET) {
00217         printf("cNet::Listen : Socket Creation Failed\n");
00218         return 0;
00219     }
00220 
00221     // bind the socket
00222     sockaddr_in sa;
00223     memset(&sa,0,sizeof(sa));
00224 
00225     sa.sin_family = AF_INET;
00226     sa.sin_port = htons(iPort);
00227     sa.sin_addr.s_addr = (uint32)0x00000000;
00228 
00229     int err;
00230     err = bind(iListenSocket,(sockaddr*)&sa,sizeof(sa));
00231     if (err != 0) {
00232         printf("cNet::Listen : BIND ERROR %d %d(%s)\n",err,errno,strerror(errno));//WSAECONNREFUSED
00233         closesocket(iListenSocket);
00234         return 0;
00235     }
00236 
00237     // start listening
00238     err = listen(iListenSocket,SOMAXCONN);
00239     if (err != 0) {
00240         printf("cNet::Listen : LISTEN ERROR %d\n",err);
00241         closesocket(iListenSocket);
00242         return 0;
00243     }
00244 
00245     // success
00246     return new cNetListener(iListenSocket,iPort);
00247 }
00248 
00249 
00250 // ****** ****** ****** cConnection
00251 
00252 
00253 
00254 
00255 
00257 cConnection::cConnection        ()
00258     : miSocket(INVALID_SOCKET), mbOwnBuffers(true), miPort(0), miRemoteAddr(0) { PROFILE
00259     Init();
00260 }
00261 
00263 cConnection::cConnection        (cConnection* con)
00264     : miSocket(INVALID_SOCKET), mbOwnBuffers(false), miPort(0), miRemoteAddr(0), 
00265         mpInBuffer(con->mpOutBuffer), mpOutBuffer(con->mpInBuffer) { PROFILE
00266     Init();
00267 }
00268 
00269 
00271 cConnection::cConnection        (const int iSocket,const char* szHost,const int iPort,const uint32 iIP)
00272     : miSocket(iSocket), mbOwnBuffers(true), miPort(iPort), miRemoteAddr(iIP) { PROFILE
00273     Init();
00274     //printf("cConnection : connection to (%s:%d)(%d.%d.%d.%d)\n",szHost,iPort,mIP[0],mIP[1],mIP[2],mIP[3]);
00275 }
00276 
00278 cConnection::cConnection        (const int iSocket,const uint32 iIP)
00279     : miSocket(iSocket), mbOwnBuffers(true), miPort(0), miRemoteAddr(iIP) { PROFILE
00280     Init();
00281     //printf("cConnection : connection from (%d.%d.%d.%d)\n",mIP[0],mIP[1],mIP[2],mIP[3]);
00282 }
00283 
00284 void    cConnection::Init   () { PROFILE
00285     if (mbOwnBuffers) {
00286         mpInBuffer =    new cFIFO(kConStartSpace);
00287         mpOutBuffer =   new cFIFO(kConStartSpace);
00288     }
00289     
00290     mIP[0] = ((unsigned char*)&miRemoteAddr)[0];
00291     mIP[1] = ((unsigned char*)&miRemoteAddr)[1];
00292     mIP[2] = ((unsigned char*)&miRemoteAddr)[2];
00293     mIP[3] = ((unsigned char*)&miRemoteAddr)[3];
00294     cNet::GetSingleton().mlCons.insert(this);
00295 }
00296 
00297 void    cConnection::Close      () { PROFILE
00298     if (miSocket != INVALID_SOCKET) {
00299         closesocket(miSocket);
00300         //shutdown(miSocket,SHUT_RDWR); // TODO ?? close ???
00301         //closesocket(INVALID_SOCKET);
00302         miSocket = INVALID_SOCKET;
00303     }
00304 }
00305 
00306 bool    cConnection::IsLocal    () { return miSocket == INVALID_SOCKET; }
00307 
00308 cConnection::~cConnection       () { PROFILE
00309     Close();
00310     cNet::GetSingleton().mlCons.erase(this);
00311     if (mbOwnBuffers) {
00312         delete mpInBuffer;
00313         delete mpOutBuffer;
00314     }
00315 }
00316 
00318 void    cConnection::SendPush       (cFIFO& source,const bool bWrite) { PROFILE
00319     //printf("cConnection::SendPush, sourcelen=%d, write=%d\n",source.size(),bWrite?1:0);
00320     assert(mpOutBuffer);
00321     if (source.size() == 0) return;
00322 
00323     size_t res = (miSocket == INVALID_SOCKET || mpOutBuffer->size() > 0 || !bWrite) ? 0 : send(miSocket,source.HackGetRawReader(),source.size(),0);
00324     if (res >= 0) {
00325         if (res < source.size()) { // push the rest onto the outbuffer
00326             //if (miSocket != INVALID_SOCKET) printf("cConnection::SendPush : %d bytes had to be pushed (old fifo-size=%d)\n",source.size()-res,mpOutBuffer->size());
00327             mpOutBuffer->PushRaw(source.HackGetRawReader()-res,source.size()-res);
00328         }
00329     } else if (res < 0) {
00330         //printf("cConnection : write : dead connection found\n");
00331         //cNet::GetSingleton().mlCons.erase(this);
00332         miSocket = INVALID_SOCKET;
00333         cNet::GetSingleton().mlDyingCons.insert(this);
00334         return;
00335     }
00336 }
00337 
00338 void    cConnection::Step       (const bool bRead,const bool bWrite, const bool bExcept) { PROFILE
00339     if (miSocket == INVALID_SOCKET) return;
00340     assert(mpOutBuffer);
00341     assert(mpInBuffer);
00342     int res;
00343 
00344     // write
00345     if (bWrite && mpOutBuffer->size() > 0) {
00346         res = send(miSocket,mpOutBuffer->HackGetRawReader(),mpOutBuffer->size(),0);
00347         if (res > 0) {
00348             mpOutBuffer->PopRaw(res);
00349         } else if (res < 0) {
00350             //printf("cConnection : write : dead connection found\n");
00351             //cNet::GetSingleton().mlCons.erase(this);
00352             miSocket = INVALID_SOCKET;
00353             cNet::GetSingleton().mlDyingCons.insert(this);
00354             return;
00355         }
00356     }
00357 
00358     // read
00359     if (bRead) {
00360         char *rw = mpInBuffer->HackGetRawWriter(kConMinRecvSpace);
00361         int fs = mpInBuffer->HackGetFreeSpace();
00362         res = recv(miSocket,rw,fs,0);
00363         if (res > 0) {
00364             //printf("netread reserve=%d freespace=%d read=%d\n",kConMinRecvSpace,freespace,res);
00365             mpInBuffer->HackAddLength(res);
00366         } else if(res < 0) {
00367             //printf("cConnection : read : dead connection found\n");
00368             //cNet::GetSingleton().mlCons.erase(this);
00369             miSocket = INVALID_SOCKET;
00370             cNet::GetSingleton().mlDyingCons.insert(this);
00371             return;
00372         } else {
00373             //printf("cConnection : read : closed by peer\n");
00374             //cNet::GetSingleton().mlCons.erase(this);
00375             miSocket = INVALID_SOCKET;
00376             cNet::GetSingleton().mlDyingCons.insert(this);
00377             return;
00378         }
00379     }
00380 }
00381 
00382 
00383 
00384 // ****** ****** ****** cConnection
00385 
00386 
00387 
00388 cBroadcast::cBroadcast() : mOutBuffer(kConStartSpace) { PROFILE cNet::GetSingleton().mlBroadCasts.insert(this); }
00389 cBroadcast::~cBroadcast() {}
00390 
00391 void    cBroadcast::Step        () { PROFILE
00392     //printf("cBroadcast::Step, cons=%d, buffersize=%d \n",mlCons.size(),mOutBuffer.size());
00393     if (mOutBuffer.size() == 0) return; // nothing to do
00394     if (mlCons.size() == 0) {
00395         mOutBuffer.Clear();
00396         return; // nothing to do
00397     }
00398 
00399     bool bWrite;
00400     int res,mysocket,imax=0;
00401     timeval timeout;
00402     timeout.tv_sec = 0;
00403     timeout.tv_usec = 0;
00404 
00405     FD_ZERO(&sSelectSet_Write);
00406 
00407     for (std::set<cConnection*>::iterator itor=mlCons.begin(); itor!=mlCons.end(); ++itor) {
00408         mysocket = (*itor)->miSocket;
00409         if (mysocket != INVALID_SOCKET) {
00410             if (imax < mysocket)
00411                 imax = mysocket;
00412             FD_SET((unsigned int)mysocket,&sSelectSet_Write);
00413         }
00414     }
00415 
00416     if (imax > 0)
00417         res = select(imax+1,0,&sSelectSet_Write,0,&timeout);
00418 
00419     for (std::set<cConnection*>::iterator itor=mlCons.begin(); itor!=mlCons.end(); ++itor) {
00420         // bWrite is set if writing to the socket is possible, even if not the data is still pushed onto the outbuffer of the con
00421         bWrite = (*itor)->miSocket != INVALID_SOCKET && FD_ISSET((unsigned int)(*itor)->miSocket,&sSelectSet_Write) != 0;
00422         (*itor)->SendPush(mOutBuffer, bWrite);
00423     }
00424 
00425     mOutBuffer.Clear();
00426 }
00427 
00428 
00429 
00430 // ****** ****** ****** cNetListener
00431 
00432 
00433 
00434 cNetListener::cNetListener  (int iListenSocket,int iPort) : miPort(iPort), miListenSocket(iListenSocket) { PROFILE
00435     cNet::GetSingleton().mlListener.insert(this);
00436 }
00437 
00438 cNetListener::~cNetListener () { PROFILE
00439     if (miListenSocket != INVALID_SOCKET) {
00440         closesocket(miListenSocket);
00441         miListenSocket = INVALID_SOCKET;
00442     }
00443 
00444     cNet::GetSingleton().mlListener.erase(this);
00445 }
00446 
00447 void    cNetListener::Step  () { PROFILE
00448     if (miListenSocket == INVALID_SOCKET) return;
00449 
00450     // accept
00451 
00452     timeval timeout;
00453     timeout.tv_sec = 0;
00454     timeout.tv_usec = 0;
00455 
00456     fd_set  conn;
00457     FD_ZERO(&conn); // Set the data in conn to nothing
00458     FD_SET((unsigned int)miListenSocket, &conn); // Tell it to get the data from the Listening Socket
00459 
00460     int     selres;
00461     selres = select(miListenSocket+1, &conn, NULL, NULL, &timeout); // Is there any data coming in?
00462 
00463     // noone there
00464     if (selres <= 0) return;
00465 
00466     // someone is joining
00467     int     consocket;
00468     struct  sockaddr_in their_addr;
00469     socklen_t   sin_size;
00470 
00471     sin_size = sizeof(struct sockaddr_in);
00472     consocket = accept(miListenSocket,(struct sockaddr *)&their_addr, &sin_size);
00473 
00474     if (consocket != INVALID_SOCKET) {
00475         //printf("cNetListener : connection accepted\n");
00476         mlCons.insert(new cConnection(consocket,their_addr.sin_addr.s_addr));
00477     }
00478 }
00479 
00480 cConnection*    cNetListener::PopAccepted () { PROFILE
00481     if (mlCons.size() == 0) return 0;
00482     cConnection* con = *mlCons.begin();
00483     mlCons.erase(con);
00484     return con;
00485 }
00486 
00487 
00488 
00489 // ****** ****** ****** cUDP_ReceiveSocket
00490 
00491 cUDP_ReceiveSocket::cUDP_ReceiveSocket  (const int iPort) : miPort(iPort) {
00492     struct  sockaddr_in     host_address;
00493         
00494     miSocket = socket(AF_INET,  SOCK_DGRAM, IPPROTO_UDP);
00495     if (miSocket < 0) { 
00496         printf("cUDP_ReceiveSocket : error opening socket : %d\n",miSocket);
00497         miSocket = INVALID_SOCKET;
00498         return;
00499     }
00500 
00501     memset((void*)&host_address,    0,  sizeof(host_address));
00502     host_address.sin_family         =AF_INET;
00503     host_address.sin_addr.s_addr    =INADDR_ANY;
00504     host_address.sin_port           =htons(miPort);
00505     int res = bind(miSocket,(struct sockaddr*)&host_address,sizeof(host_address));
00506     if (res < 0) { 
00507         printf("cUDP_ReceiveSocket : error binding socket to port %d : %d\n",miPort,res);
00508         // TODO : set error flag or something like that ?
00509     }
00510 }
00511 
00512 cUDP_ReceiveSocket::~cUDP_ReceiveSocket () {
00513     if (miSocket != INVALID_SOCKET) { closesocket(miSocket); miSocket = INVALID_SOCKET; }
00514 }
00515 
00516 int     cUDP_ReceiveSocket::Receive     (cFIFO& pFIFO,uint32& iAddr) {
00517     if (miSocket == INVALID_SOCKET) return 0;
00518     
00519     // recvfrom is blocking, so use select to check if there is data available to read before calling it
00520     if (1) {
00521         int res,mysocket,imax=0;
00522         timeval timeout;
00523         timeout.tv_sec = 0;
00524         timeout.tv_usec = 0;
00525 
00526         FD_ZERO(&sSelectSet_Read);
00527         FD_ZERO(&sSelectSet_Write);
00528         FD_ZERO(&sSelectSet_Except);
00529     
00530         FD_SET((unsigned int)miSocket,&sSelectSet_Read);
00531         FD_SET((unsigned int)miSocket,&sSelectSet_Write);
00532         FD_SET((unsigned int)miSocket,&sSelectSet_Except);
00533         
00534         imax = miSocket;
00535         res = select(imax+1,&sSelectSet_Read,&sSelectSet_Write,&sSelectSet_Except,&timeout);
00536         
00537         if (FD_ISSET((unsigned int)miSocket,&sSelectSet_Read) == 0) return 0; // no data to read
00538     }
00539     
00540     static struct sockaddr_in   remote_address;
00541     static bool init_remote_address = true;
00542     if (init_remote_address) {
00543         init_remote_address = false;
00544         memset((void*)&remote_address,  0,  sizeof(remote_address));
00545         remote_address.sin_family       = AF_INET;
00546     }
00547     remote_address.sin_port         = htons(miPort);
00548     socklen_t remote_address_size = sizeof(remote_address);
00549     //printf("cUDP_ReceiveSocket::Receive before recvfrom\n");
00550     // warning, recvfrom is blocking , use select (see above)
00551     int res = recvfrom(miSocket,pFIFO.HackGetRawWriter(kMaxUDPMsgLen),kMaxUDPMsgLen,0,(struct sockaddr*)&remote_address,&remote_address_size);
00552     //printf("cUDP_ReceiveSocket::Receive after recvfrom = %d\n",res);
00553     if (res > 0) pFIFO.HackAddLength(res);
00554     iAddr = remote_address.sin_addr.s_addr;
00555     return res;
00556 }
00557 
00558 // ****** ****** ****** cUDP_SendSocket
00559 
00560 cUDP_SendSocket::cUDP_SendSocket        () {
00561     miSocket = socket(AF_INET,  SOCK_DGRAM, IPPROTO_UDP);
00562     if (miSocket < 0) {
00563         printf("cUDP_SendSocket : error opening socket : %d\n",miSocket);
00564         miSocket = INVALID_SOCKET;
00565     }
00566     
00567     char broadcast = 1;
00568     setsockopt(miSocket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
00569     
00570     /*
00571     static struct sockaddr_in cli_addr;
00572     memset(&cli_addr, 0, sizeof(cli_addr));
00573     cli_addr.sin_family      = AF_INET;
00574     cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);
00575     cli_addr.sin_port        = htons(0); 
00576     bind(miSocket, (struct sockaddr *) &cli_addr, sizeof(cli_addr));
00577     */
00578 }
00579 
00580 cUDP_SendSocket::~cUDP_SendSocket   () {
00581     if (miSocket != INVALID_SOCKET) { closesocket(miSocket); miSocket = INVALID_SOCKET; }
00582 }
00583 
00584 void cUDP_SendSocket::SetBroadcast  (char broadcast) {
00585     if (miSocket) {
00586         // TODO this should also work under windows
00587 #ifndef WIN32
00588         int p = 0;
00589         if(broadcast > 0)p = 1;
00590         setsockopt(miSocket, SOL_SOCKET, SO_BROADCAST, &p, sizeof(p));
00591 #endif
00592     }
00593 }
00594 
00595 int     cUDP_SendSocket::Send       (const uint32 iAddr,const int iPort,const char* pData,const int iDataLen) {
00596     if (miSocket == INVALID_SOCKET) return 0;
00597     //printf("cUDP_SendSocket::Send addr=0x%08x, port=%d datalen=%d\n",iAddr,iPort,iDataLen);
00598     static struct sockaddr_in remote_address;
00599     static bool init_remote_address = true;
00600     if (init_remote_address) {
00601         init_remote_address = false;
00602         memset((void*)&remote_address,  0,  sizeof(remote_address));
00603         remote_address.sin_family       = AF_INET;
00604         remote_address.sin_port         = htons(iPort);
00605     }
00606     remote_address.sin_addr.s_addr  = iAddr; // no htonl here currently, the source from where iAddr comes doesn't use htonl either
00607     return sendto(miSocket,pData,iDataLen,0,(struct sockaddr*)&remote_address,sizeof(remote_address));
00608 }
00609 
00610 int     cUDP_SendSocket::Send       (const uint32 iAddr,const int iPort,cFIFO& pFIFO,const int iDataLen) {
00611     assert(iDataLen <= pFIFO.size() && "cUDP_SendSocket::Send fifo underrun");
00612     return Send(iAddr,iPort,pFIFO.HackGetRawReader(),(iDataLen>0&&iDataLen<=pFIFO.size())?iDataLen:pFIFO.size());
00613 }
00614 
00615 // ****** ****** ****** END
00616 
00617 };

Generated on Wed Feb 8 06:00:13 2012 for cpp by  doxygen 1.5.6