00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
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
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
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
00146 sendMC((NetworkMessage*) Buffer);
00147 }
00148
00149
00150 void
00151 SocketMC::receive(void *Buffer, unsigned long)
00152 throw (NetworkError, NetworkSignal)
00153 {
00154
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 }