00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "certi.hh"
00023 #include "SocketUDP.hh"
00024 #include "PrettyDebug.hh"
00025 #include <cstdlib>
00026 #include <cstring>
00027
00028 #ifndef MAXHOSTNAMELEN
00029 #define MAXHOSTNAMELEN 4096
00030 #endif
00031
00032 #ifdef _WIN32
00033 #include "SocketTCP.hh"
00034 #else
00035 #include <iostream>
00036 #include <sstream>
00037 #include <unistd.h>
00038 #include <strings.h>
00039 #endif
00040 #include <assert.h>
00041 #include <errno.h>
00042
00043 using std::cout ;
00044 using std::endl ;
00045
00046 namespace certi {
00047
00048 static pdCDebug D("SOCKUDP", "(SocketUDP) - ");
00049
00050
00051 void
00052 SocketUDP::attach(int socket_ouvert, unsigned long Adresse, unsigned int port)
00053 throw (NetworkError,
00054 NetworkSignal)
00055 {
00056 assert(!_est_init_udp);
00057
00058 PhysicalLink = false ;
00059
00060 _socket_udp = socket_ouvert ;
00061
00062 memset((struct sockaddr_in *) &sock_distant, 0, sizeof(struct sockaddr_in));
00063
00064 sock_distant.sin_addr.s_addr = htonl(Adresse);
00065 sock_distant.sin_family = AF_INET ;
00066 sock_distant.sin_port = port ;
00067
00068 _est_init_udp = true ;
00069
00070 D.Out(pdDebug, "Attaching the federate to his address and to his peer...");
00071 }
00072
00073
00074 int
00075 SocketUDP::bind()
00076 {
00077 assert(!_est_init_udp);
00078
00079 long result = ::bind(_socket_udp, (sockaddr *)&sock_local,
00080 sizeof(struct sockaddr_in));
00081
00082 return ((result == 0) ? 1 : 0);
00083 }
00084
00085
00087 void
00088 SocketUDP::createConnection(const char *server_name, unsigned int port)
00089 throw (NetworkError)
00090 {
00091
00092 struct sockaddr_in sock_temp ;
00093 char localhost[4096] ;
00094 std::stringstream msg;
00095 struct hostent * hp_local;
00096
00097 #ifdef _WIN32 //netDot
00098 int taille = sizeof(struct sockaddr_in);
00099 #else
00100 socklen_t taille = sizeof(struct sockaddr_in);
00101 #endif
00102
00103 assert(!_est_init_udp);
00104
00105
00106 memset(&sock_local, 0, sizeof(struct sockaddr_in));
00107 hp_local = NULL;
00108
00109 gethostname(localhost, 4096);
00110
00111 if ((hp_local = gethostbyname(localhost)) == NULL)
00112 {
00113 msg << "gethostbyname gave NULL answer for hostname <"
00114 << localhost
00115 << "> with error <"
00116 << strerror(errno)
00117 << ">";
00118 throw NetworkError(msg.str().c_str());
00119 }
00120
00121 #ifdef _WIN32
00122 memcpy((char*)&sock_local.sin_addr,(char *)hp_local->h_addr, hp_local->h_length);
00123 #else
00124 bcopy((char*)hp_local->h_addr, (char *) &sock_local.sin_addr,hp_local->h_length);
00125 #endif
00126
00127
00128 sock_local.sin_family = AF_INET;
00129 sock_local.sin_port = 0 ;
00130
00131 if (!open())
00132 {
00133 msg << "Cannot Open Socket open gave error < "
00134 << strerror(errno)
00135 << ">";
00136 throw NetworkError(msg.str().c_str());
00137 }
00138
00139 if (!bind())
00140 {
00141 msg << "Cannot Bind Socket bind gave error < "
00142 << strerror(errno)
00143 << ">";
00144 throw NetworkError(msg.str().c_str());
00145 }
00146
00147
00148 getsockname(_socket_udp, (sockaddr *)&sock_temp, &taille);
00149
00150 sock_local.sin_port = sock_temp.sin_port ;
00151 _est_init_udp = true ;
00152 }
00153
00154
00156 void
00157 SocketUDP::createUDPServer(unsigned int port)
00158 throw (NetworkError, NetworkSignal)
00159 {
00160 assert(!_est_init_udp);
00161
00162 char localhost[MAXHOSTNAMELEN+1] ;
00163 std::stringstream msg;
00164 struct hostent * hp_local=NULL;
00165
00166
00167 memset((struct sockaddr_in *) &sock_local, 0, sizeof(struct sockaddr_in));
00168
00169 gethostname(localhost, MAXHOSTNAMELEN);
00170
00171 hp_local = (struct hostent *) gethostbyname(localhost);
00172 if (NULL == hp_local)
00173 {
00174 msg << "gethostbyname gave NULL answer for hostname <"
00175 << localhost
00176 << "> with error <"
00177 << strerror(errno)
00178 << ">";
00179
00180 throw NetworkError(msg.str().c_str());
00181 }
00182
00183 memcpy((char *) &sock_local.sin_addr,(char *)hp_local->h_addr, hp_local->h_length);
00184 sock_local.sin_family = hp_local->h_addrtype ;
00185 sock_local.sin_port = htons((u_short)port);
00186
00187 if (!open())
00188 {
00189 perror("SocketUDP: Open");
00190 throw NetworkError("Cannot open UDP Socket");
00191 }
00192
00193 if (!bind())
00194 {
00195 perror("SocketUDP: Bind");
00196 throw NetworkError("Cannot bind UDP Socket");
00197 }
00198
00199 _est_init_udp = true ;
00200 }
00201
00202
00203 SocketUDP::SocketUDP()
00204 {
00205 _est_init_udp = false ;
00206 _socket_udp = 0;
00207
00208 hp_distant = NULL ;
00209 PhysicalLink = true ;
00210
00211 BufferSize = 0 ;
00212 SentBytesCount = 0 ;
00213 RcvdBytesCount = 0 ;
00214
00215 #ifdef _WIN32 //netDot
00216 SocketTCP::winsockStartup();
00217 #endif
00218 }
00219
00220
00221 SocketUDP::~SocketUDP()
00222 {
00223
00224 if (_est_init_udp)
00225 close();
00226
00227 #ifdef _WIN32 //netDot
00228 SocketTCP::winsockShutdown();
00229 #endif
00230
00231 #ifdef RTI_PRINTS_STATISTICS
00232 cout << " UDP Socket " ;
00233 cout.width(2);
00234 cout << _socket_udp << " : total = " ;
00235 cout.width(9);
00236 cout << SentBytesCount << "b sent " << endl ;
00237 cout << " UDP Socket " ;
00238 cout.width(2);
00239 cout << _socket_udp << " : total = " ;
00240 cout.width(9);
00241 cout << RcvdBytesCount << "b received" << endl ;
00242 #endif
00243 }
00244
00245
00246 void
00247 SocketUDP::send(const unsigned char * Message, size_t Size)
00248 throw (NetworkError, NetworkSignal)
00249 {
00250
00251 D.Out(pdDebug, "Beginning to send UDP message... Size = %ld", Size);
00252 assert(_est_init_udp);
00253
00254 int sent = sendto(_socket_udp, (char*)Message, Size, 0,
00255 (struct sockaddr *)&sock_distant, sizeof(sock_distant));
00256 if (sent < 0)
00257 {
00258 perror("Sendto");
00259 throw NetworkError("cannot sendto");
00260 };
00261 D.Out(pdDebug, "Sent UDP message.");
00262 SentBytesCount += sent ;
00263 }
00264
00265
00266 void
00267 SocketUDP::close()
00268 {
00269 if (_est_init_udp)
00270 {
00271 D.Out(pdDebug, "Closing UDP object...");
00272 _est_init_udp = false ;
00273 if (PhysicalLink)
00274 {
00275 D.Out(pdDebug, "Closing physical UDP link...");
00276 #ifdef _WIN32 //netDot
00277 ::closesocket(_socket_udp);
00278 #else
00279 ::close(_socket_udp);
00280 #endif
00281 }
00282 }
00283 }
00284
00285
00286 unsigned long
00287 SocketUDP::getAddr() const
00288 {
00289 D.Out(pdDebug, "Hostname is %ul...", sock_local.sin_addr.s_addr);
00290 return(sock_local.sin_addr.s_addr);
00291 }
00292
00293
00294 unsigned int
00295 SocketUDP::getPort() const
00296 {
00297 D.Out(pdDebug, "UDP port is %ud...", sock_local.sin_port);
00298 return sock_local.sin_port ;
00299 }
00300
00301
00305 bool
00306 SocketUDP::isDataReady() const
00307 {
00308 return BufferSize > 0 ;
00309 }
00310
00311
00312 int SocketUDP::open()
00313 {
00314 #ifdef _WIN32 //netDot
00315 assert(SocketTCP::winsockInitialized());
00316 #endif
00317
00318 _socket_udp = socket(AF_INET, SOCK_DGRAM, 0);
00319 return _socket_udp >= 0 ;
00320 }
00321
00322
00323 void
00324 SocketUDP::receive(void * Message, unsigned long Size)
00325 throw (NetworkError, NetworkSignal)
00326 {
00327 #ifdef _WIN32 //netDot
00328 int taille = sizeof(struct sockaddr_in);
00329 #else
00330 socklen_t taille = sizeof(struct sockaddr_in);
00331 #endif
00332
00333 int CR ;
00334
00335 assert(_est_init_udp);
00336
00337 D.Out(pdDebug, "Beginning to receive UDP message...");
00338 if (BufferSize == 0)
00339 {
00340 CR = recvfrom(_socket_udp,
00341 Buffer, BUFFER_MAXSIZE, 0,
00342 (struct sockaddr *)&sock_source, &taille);
00343
00344 if (CR <= 0)
00345 {
00346 perror("Recvfrom");
00347 throw NetworkError("cannot recvfrom");
00348 }
00349 else
00350 {
00351 RcvdBytesCount += CR ;
00352 BufferSize += CR ;
00353 }
00354 }
00355
00356 if (BufferSize < Size)
00357 {
00358 perror("Taille du Buffer inferieure a celle demandee");
00359 throw NetworkError("");
00360 }
00361 else
00362 {
00363 BufferSize -= Size ;
00364 memcpy(Message, (void *)Buffer, Size);
00365 memmove((void *) Buffer, (void *)(Buffer + Size), BufferSize);
00366 }
00367 }
00368
00369
00370 unsigned long
00371 SocketUDP::returnAdress() const
00372 {
00373 D.Out(pdDebug, "Retourner Adresse Machine locale...");
00374 return getAddr();
00375 }
00376
00377
00378 #ifdef _WIN32
00379 SOCKET SocketUDP::returnSocket()
00380 #else
00381 int SocketUDP::returnSocket()
00382 #endif
00383 {
00384 D.Out(pdDebug, "Retourner Socket UDP...");
00385 return _socket_udp ;
00386 }
00387
00388
00389 void
00390 SocketUDP::setPort(unsigned int port)
00391 {
00392 D.Out(pdDebug, "Affectation du Port UDP...");
00393 sock_local.sin_port=port ;
00394 }
00395
00396 }