Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

netstream.cc

Go to the documentation of this file.
00001 #ifndef PLATFORM_APERIOS
00002 #include "netstream.h"
00003 #include <iostream>
00004 #include <sstream>
00005 
00006 using namespace std;
00007 
00008 const IPaddr IPaddr::ANY(INADDR_ANY);
00009 const IPaddr IPaddr::BROADCAST(INADDR_BROADCAST);
00010 
00011 const unsigned int IPaddr::maxHostNameLen = 256;
00012 
00013 IPaddr::IPaddr() : server(), ipname(), ipport(0) { Init(); }
00014 
00015 IPaddr::IPaddr(const ipnum_t& num) : server(), ipname(), ipport(0) { Init(); set_num(num); }
00016 
00017 IPaddr::IPaddr(const ipname_t& name) : server(), ipname(), ipport(0) { Init(); set_name(name); }
00018 
00019 IPaddr::IPaddr(const ipnum_t& num, const ipport_t& port) : server(), ipname(), ipport(0) { Init(); set_addr(num,port); }
00020 
00021 IPaddr::IPaddr(const ipname_t& name, const ipport_t& port) : server(), ipname(), ipport(0) { Init(); set_addr(name,port); }
00022 
00023 bool IPaddr::set_num(const ipnum_t& num) {
00024   if(get_num()!=num) {
00025     Init();
00026     server.sin_family      = AF_INET;
00027     server.sin_addr.s_addr = htonl(num);
00028     server.sin_port        = htons(ipport);
00029     struct in_addr a;
00030     a.s_addr = server.sin_addr.s_addr;
00031     char addrname[maxHostNameLen];
00032     inet_ntop(AF_INET,&a,addrname,maxHostNameLen);
00033     ipname=addrname;
00034   }
00035   return true;
00036 }
00037 
00038 bool IPaddr::set_name(const ipname_t& name) {
00039   Init();
00040   if(name.find(":")!=ipname_t::npos) {
00041     size_t pos = name.find(":");
00042     int p;
00043     if(!(stringstream(name.substr(pos+1)) >> p) || p<0 || p>=(1<<16)) {
00044       cerr << "Bad port number " << name.substr(pos+1) << endl;
00045       return false;
00046     }
00047     set_port(p);
00048     return set_name(name.substr(0,pos));
00049   }
00050   if(!isalpha(name[0])) {
00051     // in case the string holds a dotted decimal we can convert directly
00052     struct in_addr a;
00053     if(inet_pton(AF_INET,name.c_str(),&a)<=0) {
00054       cerr << "IPaddr error: inet_pton failed: " << name << endl;
00055       server.sin_addr.s_addr = INADDR_NONE;
00056       return false;
00057     }
00058     return set_num(ntohl(a.s_addr));
00059   } else {
00060     Init();
00061     struct hostent * data = gethostbyname(name.c_str());
00062     if(data == NULL) {
00063       cerr << "IPaddr error: gethostbyname failed: " << name << endl;
00064       server.sin_addr.s_addr = INADDR_NONE;
00065       return false;
00066     }
00067     ipname=name;
00068 
00069     memcpy((char *) &server.sin_addr, data->h_addr_list[0], data->h_length);
00070     server.sin_family = data->h_addrtype;
00071     server.sin_port = htons(ipport);
00072   }
00073   return true;
00074 }
00075 
00076 IPaddr::ipname_t IPaddr::get_display_num() const {
00077   struct in_addr a;
00078   a.s_addr = server.sin_addr.s_addr;
00079   char addrname[maxHostNameLen];
00080   inet_ntop(AF_INET,&a,addrname,maxHostNameLen);
00081   return addrname;
00082 }
00083 
00084 IPaddr::ipname_t IPaddr::get_rname() const {
00085   struct in_addr a;
00086   a.s_addr = server.sin_addr.s_addr;
00087   struct hostent * data = gethostbyaddr((char*)&a,sizeof(a),AF_INET);
00088   if(data==NULL) {
00089     cerr << "IPaddr error: gethostbyaddr failed: " << ipname << endl;
00090     return "";
00091   }
00092   return data->h_name;
00093 }
00094 
00095 void IPaddr::Init() {
00096   ipname="";
00097   memset((char *) &server, 0, sizeof(server));
00098   server.sin_addr.s_addr = INADDR_NONE;
00099 }
00100 
00101 bool netstream_server::serve(const IPaddr& addr, bool useDatagram/*=false*/) {
00102   if(opsock>=0)
00103     close();
00104   tgtAddress=addr;
00105   datagram=useDatagram;
00106   
00107   // create socket
00108   opsock = ::socket(AF_INET, datagram ? (int)SOCK_DGRAM : (int)SOCK_STREAM, 0);
00109   if(opsock < 0) {
00110     perror("netstream socket");
00111     //cout << "netstream error: socket failed to create stream socket" << endl;
00112     opsock=-1;
00113     return false;
00114   }
00115   int on=1;
00116   if ( ::setsockopt ( opsock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 ) {
00117     perror("netstream SO_REUSEADDR setsockopt");
00118   }
00119 #ifdef __APPLE__
00120   if ( ::setsockopt ( opsock, SOL_SOCKET, SO_NOSIGPIPE, ( const char* ) &on, sizeof ( on ) ) == -1 ) {   
00121     perror("netstream SO_NOSIGPIPE setsockopt");   
00122   }
00123 #endif
00124   if(datagram) {
00125     if ( ::setsockopt ( opsock, SOL_SOCKET, SO_BROADCAST, ( const char* ) &on, sizeof ( on ) ) == -1 ) {
00126       perror("netstream SO_BROADCAST setsockopt");
00127     }
00128   }
00129   
00130   sockaddr_in server = addr.get_addr();
00131   
00132   // bind socket to specified address
00133   if(::bind(opsock, (const sockaddr *) &server, sizeof(server)) != 0) {
00134     //perror("netstream bind");
00135     close();
00136     return false;
00137   }
00138   
00139   // tell OS to start listening
00140   if(::listen(opsock, 0) != 0) {
00141     perror("netstream listen");
00142     close();
00143     return false;
00144   }
00145   
00146   return true;
00147 }
00148 
00149 
00150 #endif

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:45 2016 by Doxygen 1.6.3