SocketMC.cc

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------------
00002 // CERTI - HLA RunTime Infrastructure
00003 // Copyright (C) 2002-2005  ONERA
00004 //
00005 // This program is free software ; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public License
00007 // as published by the Free Software Foundation ; either version 2 of
00008 // the License, or (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful, but
00011 // WITHOUT ANY WARRANTY ; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this program ; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00018 // ----------------------------------------------------------------------------
00019 
00020 
00021 
00022 #include "SocketMC.hh"
00023 #include "config.h"
00024 
00025 #ifdef _WIN32
00026     #include "SocketTCP.hh"
00027 #else
00028     #include <arpa/inet.h>
00029     #include <unistd.h>
00030     #include <errno.h>
00031     #include <sys/time.h>
00032 #endif
00033 #include <cassert>
00034 #include <cstdlib>
00035 #include <cstring>
00036 
00037 namespace certi {
00038 
00039 // ----------------------------------------------------------------------------
00040 SocketMC::SocketMC()
00041 {
00042 _est_init_mc = false ;
00043 _num_msg = 1 ;
00044 #ifdef _WIN32
00045   SocketTCP::winsockStartup();
00046 #endif
00047 }
00048 
00049 // ----------------------------------------------------------------------------
00050 SocketMC::~SocketMC()
00051 {
00052 if (_est_init_mc) 
00053     {
00054     #ifdef _WIN32
00055          closesocket(_socket_mc);
00056          closesocket(_socket_emetteur);
00057     #else
00058 		 ::close(_socket_mc);
00059 		 ::close(_socket_emetteur);
00060     #endif
00061     _est_init_mc = false ;
00062     }
00063     
00064 #ifdef _WIN32
00065     SocketTCP::winsockShutdown();
00066 #endif
00067 
00068 }
00069 
00070 
00071 // ----------------------------------------------------------------------------
00072 void
00073 SocketMC::CreerSocketMC(char *addr, unsigned long port)
00074 {
00075     assert(addr!=NULL);
00076     CreerSocketMC(inet_addr(addr), port);
00077 }
00078 
00079 // ----------------------------------------------------------------------------
00080 void
00081 SocketMC::CreerSocketMC(unsigned long addr, unsigned long port)
00082 {
00083 struct ip_mreq _mreq ;
00084 unsigned long _mreqlen ;
00085 
00086 assert(!_est_init_mc);
00087 assert(addr>0);
00088 
00089 #ifdef _WIN32
00090     assert(SocketTCP::winsockInitialized());
00091 #endif
00092 
00093 // create receiving socket
00094 _socket_mc = socket(AF_INET, SOCK_DGRAM, 0);
00095 if (_socket_mc < 0) {
00096     perror("socket1");
00097         throw NetworkError("cannot create socket");
00098     }
00099 
00100 memset(&_sin, sizeof(_sin), sizeof(_sin));
00101 _sin.sin_family = AF_INET ;
00102 _sin.sin_addr.s_addr = htonl(INADDR_ANY);
00103 _sin.sin_port = htons(port);
00104 _sinlen = sizeof(_sin);
00105 
00106 if (bind(_socket_mc, (struct sockaddr *)&_sin, _sinlen) < 0) {
00107     perror("SocketMC: bind");
00108         throw NetworkError("cannot bind");
00109     }
00110 
00111 // joindre le groupe multiCast
00112 _mreq.imr_multiaddr.s_addr = addr ;
00113 _mreq.imr_interface.s_addr = htonl(INADDR_ANY);
00114 _mreqlen = sizeof(_mreq);
00115 if (setsockopt(_socket_mc,
00116              IPPROTO_IP,
00117              IP_ADD_MEMBERSHIP,
00118              (char *)&_mreq, _mreqlen) < 0) {
00119     perror("setsockopt");
00120         throw NetworkError("cannot setsockopt");
00121     }
00122 
00123 // creation du socket emetteur
00124 _socket_emetteur = socket(AF_INET, SOCK_DGRAM, 0);
00125 if (_socket_emetteur < 0) {
00126     perror("socket2");
00127         throw NetworkError("cannot create socket");
00128     }
00129 
00130 memset(&_sin_e, sizeof(_sin_e), sizeof(_sin_e));
00131 _sin_e.sin_family = AF_INET ;
00132 _sin_e.sin_port = htons(port);
00133 _sin_e.sin_addr.s_addr = addr ;
00134 _sinlen_e = sizeof(_sin_e);
00135 
00136 // l'initialisation de la communication multicast est reussie
00137 _est_init_mc = true ;
00138 }
00139 
00140 // ----------------------------------------------------------------------------
00141 void
00142 SocketMC::send(const unsigned char *Buffer, size_t)
00143     throw (NetworkError, NetworkSignal)
00144 {
00145     // BUG:Revoir ca en faisant le contraire(EmettreMC appelle Emettre)
00146     sendMC((NetworkMessage*) Buffer);
00147 }
00148 
00149 // ----------------------------------------------------------------------------
00150 void
00151 SocketMC::receive(void *Buffer, unsigned long)
00152     throw (NetworkError, NetworkSignal)
00153 {
00154     // BUG: Revoir ca en faisant le contraire(RecevoirMC appelle Recevoir)
00155     receiveMC((NetworkMessage*) Buffer);
00156 }
00157 
00158 // ----------------------------------------------------------------------------
00159 #ifdef _WIN32
00160     SOCKET SocketMC::returnSocket() { return _socket_mc;}
00161 #else
00162     int SocketMC::returnSocket()        { return _socket_mc;}
00163 #endif
00164                                         
00165 // ----------------------------------------------------------------------------
00166 unsigned long
00167 SocketMC::returnAdress() const
00168 {
00169     return _sin_e.sin_addr.s_addr ;
00170 }
00171 
00172 // ----------------------------------------------------------------------------
00173 void
00174 SocketMC::close()
00175 {
00176 if (_est_init_mc) {
00177     #ifdef _WIN32
00178          closesocket(_socket_mc);
00179          closesocket(_socket_emetteur);
00180     #else
00181 		 ::close(_socket_mc);
00182 		 ::close(_socket_emetteur);
00183     #endif
00184     _est_init_mc = false ;
00185     }
00186 }
00187 
00188 // ----------------------------------------------------------------------------
00189 void
00190 SocketMC::sendMC(NetworkMessage *message)
00191 {
00192     int cnt ;
00193 
00194     message->number=_num_msg ;
00195     _num_msg++ ;
00196     assert(_est_init_mc);
00197     assert(message != NULL);
00198 
00199     cnt = sendto(_socket_emetteur, (char *)message, TAILLE_MSG_RESEAU, 0,
00200                  (struct sockaddr *)&_sin_e, _sinlen_e);
00201 
00202     if (cnt < 0) {
00203     perror("Send");
00204         throw NetworkError("cannot sendto");
00205     }
00206 }
00207 
00208 // ----------------------------------------------------------------------------
00209 char *
00210 SocketMC::receiveMC(NetworkMessage *message)
00211 {
00212     int cnt ;
00213 
00214     assert(_est_init_mc);
00215 
00216     cnt = recvfrom(_socket_mc, (char *)message, TAILLE_MSG_RESEAU, 0,
00217                    (struct sockaddr *)&_sin, &_sinlen);
00218     if (cnt < 0) {
00219     perror("Recv");
00220         throw NetworkError("cannot recvfrom");
00221     }
00222 
00223     return(inet_ntoa(_sin.sin_addr));
00224 }
00225 
00226 // ----------------------------------------------------------------------------
00234 int SocketMC::timeoutMC(int sec, int usec)
00235 {
00236 assert(_est_init_mc);
00237 
00238 struct timeval timeout ;
00239 timeout.tv_sec = sec ;
00240 timeout.tv_usec = usec ;
00241 
00242 fd_set fdset ;
00243 FD_ZERO(&fdset);
00244 FD_SET(_socket_mc, &fdset);
00245 
00246 int nb = 0 ;
00247 bool check;
00248 do
00249     {
00250     nb = select(_socket_mc+1, SELECT_TYPE_ARG234 &fdset, NULL, NULL, &timeout);
00251     
00252     #ifdef _WIN32
00253             check= (WSAGetLastError() == WSAEINTR);
00254     #else
00255             check= (errno == EINTR);
00256     #endif
00257     } while ((nb < 0) && check);
00258 
00259 return nb ;
00260 }
00261 
00262 } // namespace certi

Generated on Thu Apr 30 15:53:50 2009 for CERTIDeveloperDocumentation by doxygen 1.5.5