00001
00002
00003
00004
00005
00006
00007 #include <iostream>
00008 #include <memory>
00009 #include <stdio.h>
00010
00011
00012 #include "SysPlusPlus/syscall.h"
00013 #include "SysPlusPlus/syslib.h"
00014 #include "SysPlusPlus/Tools.h"
00015 #include "ComPlusPlus/Poll.h"
00016 #include "ComPlusPlus/SocketUdp.h"
00017 #include "SysPlusPlus/GenCfg.h"
00018 #include "SysPlusPlus/ComException.h"
00019
00020
00021 #define MAXUDP 65536
00022
00023 #include <sys/socket.h>
00024
00028 void compp::SocketUdp::NewUdpSocket() {
00029
00030 this->fd = syspp::Call::Socket ( PF_INET, SOCK_DGRAM, 0 );
00031 if ( this->fd == -1 ) {
00032 throw syspp::ComException("Panic: Cannot create socket!");
00033 }
00034
00035 IsOpen = true;
00036 FdClosed = false;
00037 }
00038
00039
00044 compp::SocketUdp::~SocketUdp() {
00045
00046 if ( this->fd == -1 )
00047 return;
00048 close ( this->fd );
00049 }
00050
00051
00056 compp::SocketUdp::SocketUdp() {
00057
00058 NewUdpSocket();
00059
00060 }
00061
00066 compp::SocketUdp::SocketUdp ( struct sockaddr_in *saddr, int len, int fd ) {
00067
00068 this->fd = fd;
00069 this->IsOpen=true;
00070 this->FdClosed = false;
00071 }
00072
00073
00080 compp::SocketUdp::SocketUdp(const std::string & Addr, int port) {
00081
00082 NewUdpSocket();
00083 this->Bind ( Addr, port );
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 compp::SocketUdp::SocketUdp( int port) {
00093
00094 NewUdpSocket();
00095 this->Bind ( SocketANYHOST, port );
00096
00097 }
00098
00099
00104 void compp::SocketUdp::Bind ( const std::string & addr, int port) {
00105 struct sockaddr_in ad;
00106 in_addr_t adv4;
00107
00108
00109 struct hostent *hent;
00110
00111 (void) memset((void *) &adv4, 0, sizeof (adv4));
00112
00113 if ( addr == SocketANYHOST ) {
00114 memset ( & ad.sin_addr, 0, sizeof (ad.sin_addr));
00115 } else {
00116 if ( INADDR_NONE == ( adv4 = inet_addr ( addr.c_str() ))) {
00117 if ( this->GetUseDNS() ) {
00118 if (NULL == (hent = syspp::Lib::Gethostbyname (addr.c_str() ))) {
00119
00120
00121 throw syspp::ComException ( "compp::SocketUdp:Bind Cannot Resolve Hostname " );
00122 } else {
00123 std::memmove( &(adv4), *hent->h_addr_list , sizeof(adv4));
00124 ad.sin_addr.s_addr = adv4;
00125 }
00126 }
00127 } else {
00128 ad.sin_addr.s_addr = adv4;
00129 }
00130 }
00131 ad.sin_family = AF_INET;
00132 ad.sin_port = htons(port);
00133
00134 #if 1
00135 if ( -1 == syspp::Call::Bind( this->fd, (struct sockaddr* )&ad, (socklen_t) sizeof(ad))) {
00136 #else
00137 if ( -1 == syspp::Call::Bind( this->fd, (struct sockaddr* )&ad, sizeof(ad))) {
00138 #endif
00139
00140
00141
00142 throw syspp::ComException ( "compp::SocketUdp::Bind Cannot Bind " );
00143 }
00144 this->SocketPort = port;
00145 State = Bound;
00146 }
00147
00151 void compp::SocketUdp::Bind ( const int port ) {
00152 this->Bind ( SocketANYHOST, port );
00153 }
00154
00158 bool compp::SocketUdp::Connect( const std::string &addr, const int port ){
00159 if ( this->fd == -1 )
00160 NewUdpSocket();
00161
00162 IsOpen = true;
00163 FdClosed = false;
00164
00165 return _Connect( addr, port );
00166 }
00167
00168 void compp::SocketUdp::SetSockOptBroadcast( bool yes ) {
00169 int opt;
00170
00171 if ( yes == true )
00172 opt = 1;
00173 else
00174 opt = 0;
00175
00176 #if 1
00177 if ( 0 != syspp::Call::Setsockopt (this->fd, SOL_SOCKET, SO_BROADCAST, (void*)&opt, (socklen_t)sizeof(opt) )) {
00178 #else
00179 if ( 0 != syspp::Call::Setsockopt (this->fd, SOL_SOCKET, SO_BROADCAST, (void*)&opt, sizeof(opt) )) {
00180 #endif
00181 throw syspp::ComException("Cannot set option BROADCAST");
00182 }
00183 }
00184
00185
00186
00187
00188
00189 void compp::SocketUdp::SetSockOptJoinMulticastGroup ( const std::string & group ) {
00190 #ifndef IP_ADD_MEMBERSHIP
00191 throw syspp::ComException ( "Cannot join multicast group. Multicasting not supported." );
00192 #else
00193 struct ip_mreq mp;
00194 struct in_addr ad;
00195
00196 _MkIPAddrIPV4(group, &ad);
00197
00198 mp.imr_multiaddr = ad;
00199
00200 _MkIPAddrIPV4("0.0.0.0", &ad);
00201 mp.imr_interface = (struct in_addr) ad;
00202
00203 if ( -1 == syspp::Call::Setsockopt (this->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mp, sizeof(mp)) )
00204 throw syspp::ComException ( "Cannot join multicast group" );
00205 #endif
00206
00207 }
00208
00209
00210
00211
00212
00213 void compp::SocketUdp::SetSockOptWithdrawMulticastGroup ( const std::string & group ) {
00214 #ifndef IP_DROP_MEMBERSHIP
00215 return ;
00216 #else
00217
00218 struct ip_mreq mp;
00219 struct in_addr ad;
00220
00221 _MkIPAddrIPV4(group, &ad);
00222
00223 mp.imr_multiaddr = ad;
00224 _MkIPAddrIPV4("0.0.0.0", &ad);
00225
00226 mp.imr_interface = ad;
00227
00228 if ( -1 == syspp::Call::Setsockopt (this->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mp, sizeof(mp))) {
00229 throw syspp::ComException ( "Cannot leave multicast group" );
00230 }
00231 #endif
00232 }
00233
00234
00235
00236
00237
00238 void compp::SocketUdp::SetSockOptMulticastLoop ( bool val ) {
00239 #ifndef IP_MULTICAST_LOOP
00240 return ;
00241 #else
00242
00243 int i = val ? 1 : 0;
00244
00245 if ( -1 == syspp::Call::Setsockopt (this->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &i, sizeof(i))) {
00246 throw syspp::ComException ( "Cannot SetOpt Multicast Loopback " );
00247 }
00248 #endif
00249 }
00250
00251
00252
00253
00254 void compp::SocketUdp::SetSockOptMulticastTTL ( int val ) {
00255 #ifndef IP_MULTICAST_TTL
00256 return ;
00257 #else
00258
00259 if ( val < 1 )
00260 return ;
00261
00262 if ( -1 == syspp::Call::Setsockopt (this->fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, sizeof(val))) {
00263 throw syspp::ComException ( "Cannot SetOpt Multicast TTL " );
00264 }
00265 #endif
00266 }
00267
00268 int compp::SocketUdp::Write ( char *buf, int count ) {
00269
00270 if ( count > MAXUDP ) {
00271 throw syspp::ComException ( "compp::SocketUDP Cannot write more than 65 K on UDP" );
00272 }
00273
00274 int ret ;
00275 ret = this->Send(buf, count);
00276 return ret;
00277
00278 }
00279
00280
00281 int compp::SocketUdp::Write ( const std::string & buf ) {
00282
00283 if ( buf.length() > MAXUDP ) {
00284 throw syspp::ComException ( "compp::SocketUDP Cannot write more than 65 K on UDP" );
00285 }
00286
00287 int ret;
00288 ret = this->Send(buf.c_str(), buf.length());
00289 return ret;
00290
00291 }
00292
00293
00294 int compp::SocketUdp::Writen ( const char *buf, int count ) {
00295
00296 if ( count > MAXUDP ) {
00297 throw syspp::ComException ( "compp::SocketUDP Cannot write more than 65 K on UDP" );
00298 }
00299
00300 int ret;
00301 ret = this->Send(buf, count );
00302 return ret;
00303
00304 }
00305
00306
00307 int compp::SocketUdp::Writen ( const std::string & buf ) {
00308
00309 if ( buf.length() > MAXUDP ) {
00310 throw syspp::ComException ( "compp::SocketUDP Cannot write more than 65 K on UDP" );
00311 }
00312 this->Send(buf.c_str() , buf.length() );
00313 return buf.length();
00314 }
00315
00316 int compp::SocketUdp::Read ( char *buf, int count, std::string &host, int & port ) {
00317
00318 if ( count > MAXUDP ) {
00319 throw syspp::ComException ( "compp::SocketUDP Cannot read more than 65 K on UDP" );
00320 }
00321
00322 if ( count <= 0 )
00323 return count;
00324 int retlen ;
00325
00326 struct sockaddr_in from;
00327 int lenfrom= sizeof (struct sockaddr_in) ;
00328
00329 retlen = syspp::Call::Recvfrom(fd, (void *) buf, count, 0, (struct sockaddr*) &from, &lenfrom);
00330 host= inet_ntoa ( (const in_addr &) from.sin_addr.s_addr ) ;
00331 port = ntohs( from.sin_port);
00332
00333 char ctmp[60];
00334 sprintf ( ctmp, "%u", port );
00335 ContextString=host;
00336 ContextString+=":";
00337 ContextString+=ctmp;
00338
00339 return retlen;
00340 }
00341
00342 int compp::SocketUdp::Read ( std::string &buf, int count, std::string &host, int & port ) {
00343
00344 if ( count > MAXUDP ) {
00345 throw syspp::ComException ( "compp::SocketUDP Cannot read more than 65 K on UDP" );
00346 }
00347
00348 if ( count <= 0 )
00349 return count;
00350
00351 int retlen ;
00352 std::auto_ptr<char> c (new char[count+1]);
00353
00354 struct sockaddr_in from;
00355 int len = sizeof( struct in_addr );
00356
00357 retlen = syspp::Call::Recvfrom(fd, (void *) c.get(), count, 0, (struct sockaddr *) &from, &len);
00358 host= inet_ntoa ( (const in_addr &) from.sin_addr.s_addr ) ;
00359 port = ntohs( from.sin_port);
00360 SocketAddress = host ;
00361 SocketPort = port;
00362
00363 char ctmp[60];
00364 sprintf ( ctmp, "%u", port );
00365 ContextString=host;
00366 ContextString+=":";
00367 ContextString+=ctmp;
00368
00369 buf.assign ( (char*) c.get(), retlen);
00370
00371 return retlen;
00372 }
00373
00374 int compp::SocketUdp::Read ( std::string &buf, std::string &host, int & port ) {
00375
00376 char c[ MAXUDP ];
00377 int retlen ;
00378
00379 struct sockaddr_in from;
00380 int len = sizeof( from );
00381
00382 retlen = syspp::Call::Recvfrom(fd, (void *) c, MaxNumBytesToRead, 0, (struct sockaddr *) &from, &len);
00383 host= inet_ntoa ( (const in_addr &) from.sin_addr.s_addr ) ;
00384 SocketAddress = host ;
00385
00386 port = ntohs( from.sin_port);
00387 SocketPort = port;
00388 buf.assign ( (char*) c, retlen);
00389
00390 char ctmp[60];
00391 sprintf ( ctmp, "%u", port );
00392 ContextString=host;
00393 ContextString+=":";
00394 ContextString+=ctmp;
00395
00396 return retlen;
00397 }
00398
00399
00405 int compp::SocketUdp::Recvfrom(void *buf, int len, int flags, std::string &from, int *fromport){
00406
00407 if ( len > MAXUDP ) {
00408 throw syspp::ComException ( "compp::SocketUDP Cannot read more than 65 K on UDP" );
00409 }
00410
00411 struct sockaddr_in fromsa;
00412 int ret;
00413 int i = sizeof ( fromsa);
00414 ret = syspp::Call::Recvfrom(this->fd, buf, len, flags, (struct sockaddr*) &fromsa, &i );
00415
00416 *fromport = ntohs (fromsa.sin_port);
00417 char *c;
00418 c = inet_ntoa((in_addr) fromsa.sin_addr );
00419 from = c;
00420
00421 if ( ret == -1 && errno != EAGAIN ) {
00422 throw syspp::ComException( "compp::SocketUDP: Error in Recvfrom");
00423 }
00424 return ret;
00425 }
00426
00431 int compp::SocketUdp::Sendto(const void *buf, size_t len, const std::string &host, int port){
00432
00433 if ( len > MAXUDP ) {
00434 throw syspp::ComException ( "compp::SocketUDP Cannot write more than 65 K on UDP" );
00435 }
00436
00437 struct sockaddr_in ad;
00438 int ret;
00439
00440 _MkSockaddrIPV4( host, (const int )port, &ad);
00441
00442 ret = syspp::Call::Sendto( this->fd, buf, len, 0,(const struct sockaddr *) &ad, (int) sizeof ( ad));
00443 if ( ret == -1 ) {
00444 throw syspp::ComException( "compp::SocketUDP: Error in SendTo");
00445 }
00446
00447 return ret;
00448 }
00449
00450
00451
00452 int compp::SocketUdp::Sendto(const void *buf, size_t len, const struct sockaddr_in &ad ){
00453
00454 if ( len > MAXUDP ) {
00455 throw syspp::ComException ( "compp::SocketUDP Cannot write more than 65 K on UDP" );
00456 }
00457
00458 int ret = syspp::Call::Sendto( this->fd, buf, len, 0,(const struct sockaddr *) &ad, (int) sizeof ( ad));
00459 if ( ret == -1 ) {
00460 throw syspp::ComException( "compp::SocketUDP: Error in SendTo");
00461 }
00462
00463 return ret;
00464 }
00465
00466 int compp::SocketUdp::Readn ( char *buf, int count ) {
00467
00468 std::string host;
00469 int port;
00470 return Read ( buf, count, host, port ) ;
00471
00472 }
00473
00474 int compp::SocketUdp::Readn ( std::string &buf, int count) {
00475
00476 std::string host;
00477 int port;
00478 return Read ( buf, count, host ,port ) ;
00479
00480 }
00481
00482