Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGDgramSocket.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 //---------------------------------------------------------------------------
00040 //  Includes
00041 //---------------------------------------------------------------------------
00042 
00043 #include <sys/types.h>
00044 #ifdef WIN32
00045 #include <windows.h>
00046 #ifndef IP_ADD_MEMBERSHIP // VS.Net defines this within winsock2.h
00047 #include <WS2TCPIP.h>
00048 #endif
00049 #include <io.h>
00050 #else
00051 #include <sys/socket.h>
00052 #include <netinet/in.h>
00053 #include <netinet/tcp.h>
00054 #include <arpa/inet.h>
00055 #include <netdb.h>
00056 #include <unistd.h>
00057 #include <fcntl.h>
00058 #include <sys/time.h>
00059 #endif
00060 #include <errno.h>
00061 #include <stdio.h>
00062 #include <math.h>
00063 #include <map>
00064 #include <OSGBase.h>
00065 #include <OSGBaseFunctions.h>
00066 #include <OSGSocketAddress.h>
00067 #include <OSGDgramSocket.h>
00068 #include <OSGNetworkMessage.h>
00069 
00070 OSG_USING_NAMESPACE
00071 
00093 /*-------------------------------------------------------------------------*/
00094 /*                            constructor destructor                       */
00095 
00100 DgramSocket::DgramSocket():
00101     Socket()
00102 {
00103 }
00104 
00107 DgramSocket::DgramSocket(const DgramSocket &source):
00108     Socket(source)
00109 {
00110 }
00111 
00112 /*-------------------------------------------------------------------------*/
00113 /*                        open                                             */
00114 
00119 void DgramSocket::open()
00120 {
00121     _sd = socket(AF_INET, SOCK_DGRAM, 0);
00122     if(_sd<0)
00123     {
00124         throw SocketError("socket()");
00125     }
00126     // all dgram sockets are allowed to send broadcast
00127     int on = 1;
00128     if(::setsockopt(_sd, 
00129                     SOL_SOCKET, SO_BROADCAST, 
00130                     (SocketOptT*)&on, sizeof(on)) < 0)
00131     {
00132         throw SocketError("setsockopt(,SOL_SOCKET,SO_BROADCAST)");
00133     }
00134     // by default, multicast only in local network
00135     setTTL(2);
00136 }
00137 
00140 void DgramSocket::close(void)
00141 {
00142 #ifdef WIN32
00143     ::closesocket(_sd);
00144 #else
00145     ::close(_sd);
00146 #endif
00147 }
00148 
00149 /*-------------------------------------------------------------------------*/
00150 /*                        read, write                                      */
00151 
00157 int DgramSocket::recvFrom(void *buf,int size,SocketAddress &from)
00158 {
00159     int len;
00160     SocketLenT addrLen=from.getSockAddrSize();
00161 
00162 #ifndef WIN32
00163     do
00164     {
00165 #endif
00166         len=recvfrom(_sd,
00167                      (char*)buf,
00168                      size,
00169                      0,
00170                      from.getSockAddr(),
00171                      &addrLen);
00172 #ifndef WIN32
00173     } 
00174     while(len < 0 && errno == EAGAIN);
00175 #endif
00176 
00177     if(len < 0)
00178     {
00179 #if defined WIN32
00180         if(getError() == WSAECONNRESET)
00181         {
00182             throw SocketConnReset("recvfrom");
00183         }
00184         if(getError() == WSAEMSGSIZE)
00185         {
00186             len=size;
00187         }
00188         else
00189 #endif
00190         throw SocketError("recvfrom()");
00191     }
00192     return len;
00193 }
00194 
00202 int DgramSocket::peekFrom(void *buf,int size,SocketAddress &from)
00203 {
00204     int len;
00205     SocketLenT addrLen=from.getSockAddrSize();
00206 
00207     len=recvfrom(_sd,
00208                  (char*)buf,
00209                  size,
00210                  MSG_PEEK,
00211                  from.getSockAddr(),
00212                  &addrLen);
00213     if(len == -1)
00214     {
00215 #if defined WIN32
00216         if(getError() == WSAECONNRESET)
00217         {
00218             throw SocketConnReset("recvfrom");
00219         }
00220         if(getError() == WSAEMSGSIZE)
00221         {
00222             len=size;
00223         }
00224         else
00225 #endif
00226         throw SocketError("recvfrom()");
00227     }
00228     return len;
00229 }
00230 
00235 int DgramSocket::recvFrom(NetworkMessage &msg,SocketAddress &from)
00236 {
00237     NetworkMessage::Header hdr;
00238     peek(&hdr,sizeof(hdr));
00239     msg.setSize(osgntohl(hdr.size));
00240     return recvFrom(msg.getBuffer(),msg.getSize(),from);
00241 }
00242 
00247 int DgramSocket::sendTo(const void *buf,int size,const SocketAddress &to)
00248 {
00249     int len;
00250 
00251     // send Request
00252     len=sendto(_sd,
00253                (const char*)buf,size,
00254 #if defined(WIN32) && defined(MSG_NOSIGNAL)
00255                MSG_NOSIGNAL,
00256 #else
00257                0,
00258 #endif
00259                to.getSockAddr(),
00260                to.getSockAddrSize());
00261 #ifdef _sgi
00262     /* Irix simetimes returns ENOBUFS on blocking write.
00263        Retry until buffer is available */
00264     while(len == -1 && errno == ENOBUFS)
00265     {
00266         usleep(100);
00267         len=sendto(_sd,
00268                    (const char*)buf,size,
00269                    0,
00270                    to.getSockAddr(),
00271                    to.getSockAddrSize());
00272     }
00273 #endif
00274 
00275     if(len == -1)
00276     {
00277         throw SocketError("sendto()");
00278     }
00279     return len;
00280 }
00281 
00286 int DgramSocket::sendTo(NetworkMessage &msg,const SocketAddress &to)
00287 {
00288     NetworkMessage::Header &hdr=msg.getHeader();
00289     hdr.size=osghtonl(msg.getSize());
00290     return sendTo(msg.getBuffer(),msg.getSize(),to);
00291 }
00292 
00293 /*-------------------------------------------------------------------------*/
00294 /*                        multicast                                        */
00295 
00299 void DgramSocket::join(const SocketAddress &group,const SocketAddress &interf)
00300 {
00301     struct ip_mreq joinAddr;
00302     int rc;
00303 
00304     // group to join
00305     joinAddr.imr_multiaddr.s_addr =
00306         ((sockaddr_in*)group.getSockAddr())->sin_addr.s_addr;
00307 
00308     // interface that joins. (equal to bind address)
00309     joinAddr.imr_interface =
00310         ((struct sockaddr_in*)interf.getSockAddr())->sin_addr;
00311     rc=setsockopt(_sd,
00312                   IPPROTO_IP,
00313                   IP_ADD_MEMBERSHIP,
00314                   (SocketOptT*)&joinAddr,
00315                   sizeof(joinAddr));
00316     if(rc < 0)
00317     {
00318         throw SocketError("setsockopt(IPPROTO_IP,IP_ADD_MEMBERSHIP)");
00319     }
00320 }
00321 
00324 void DgramSocket::leave(const SocketAddress &group,const SocketAddress &interf)
00325 {
00326     struct ip_mreq joinAddr;
00327     int rc;
00328 
00329     // group to join
00330     joinAddr.imr_multiaddr.s_addr =
00331         ((sockaddr_in*)group.getSockAddr())->sin_addr.s_addr;
00332     // interface that joins. (equal to bind address)
00333     joinAddr.imr_interface =
00334         ((sockaddr_in*)interf.getSockAddr())->sin_addr;
00335     rc=setsockopt(_sd,
00336                   IPPROTO_IP,
00337                   IP_DROP_MEMBERSHIP,
00338                   (SocketOptT*)&joinAddr,
00339                   sizeof(joinAddr));
00340     if(rc < 0)
00341     {
00342         throw SocketError("setsockopt(IPPROTO_IP,IP_DROP_MEMBERSHIP)");
00343     }
00344 }
00345 
00350 void DgramSocket::setTTL(unsigned char ttl)
00351 {
00352     int rc=setsockopt(_sd, IPPROTO_IP,IP_MULTICAST_TTL,
00353                       (SocketOptT*)&ttl,sizeof(ttl));
00354     if(rc < 0)
00355     {
00356         throw SocketError("setsockopt(IPPROTO_IP,IP_MULTICAST_TTL)");
00357     }
00358 }
00359 
00363 void DgramSocket::setMCastInterface(const SocketAddress &interf)
00364 {
00365     int rc=setsockopt(_sd,
00366                       IPPROTO_IP,
00367                       IP_MULTICAST_IF,
00368                       (SocketOptT*)interf.getSockAddr(),
00369                       interf.getSockAddrSize());
00370     if(rc < 0)
00371     {
00372         throw SocketError("setsockopt(IPPROTO_IP,IP_MULTICAST_IF)");
00373     }
00374 
00375 }
00376 
00377 /*-------------------------------------------------------------------------*/
00378 /*                        assignment                                       */
00379 
00382 const DgramSocket & DgramSocket::operator =(const DgramSocket &source)
00383 {
00384     _sd=source._sd;
00385     return *this;
00386 }
00387 
00388 /*-------------------------------------------------------------------------*/
00389 /*                              cvs id's                                   */
00390 
00391 #ifdef __sgi
00392 #pragma set woff 1174
00393 #endif
00394 
00395 #ifdef OSG_LINUX_ICC
00396 #pragma warning( disable : 177 )
00397 #endif
00398 
00399 namespace
00400 {
00401     static Char8 cvsid_cpp       [] = "@(#)$Id: $";
00402     static Char8 cvsid_hpp       [] = OSG_DGRAMSOCKET_HEADER_CVSID;
00403 }

Generated on Thu Aug 25 04:02:47 2005 for OpenSG by  doxygen 1.4.3