# 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