otsdaq  v1_01_02
 All Classes Namespaces Functions
Socket.cc
1 #include "otsdaq-core/NetworkUtilities/Socket.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
4 
5 #include <iostream>
6 #include <cassert>
7 #include <sstream>
8 
9 #include <unistd.h>
10 #include <arpa/inet.h>
11 //#include <sys/socket.h>
12 #include <netdb.h>
13 //#include <ifaddrs.h>
14 //#include <sys/ioctl.h>
15 //#if defined(SIOCGIFHWADDR)
16 //#include <net/if.h>
17 //#else
18 //#include <net/if_dl.h>
19 //#endif
20 //#include <cstdlib>
21 #include <cstring>
22 //#include <cstdio>
23 
24 using namespace ots;
25 
26 
27 //========================================================================================================================
28 Socket::Socket(void)
29 {
30  __SS__ << "ERROR: This method should never be called. There is something wrong in your inheritance scheme!" << std::endl;
31  __MOUT__ << "\n" << ss.str();
32  //FIXME: this is getting called during configure?!
33  //throw std::runtime_error(ss.str());
34 }
35 
36 //========================================================================================================================
37 Socket::Socket(const std::string &IPAddress, unsigned int port)
38 : socketNumber_(-1)
39 , IPAddress_ (IPAddress)
40 , port_ (port)
41 // maxSocketSize_(maxSocketSize)
42 {
43  __MOUT__ << std::endl;
44  //network stuff
45  socketAddress_.sin_family = AF_INET;// use IPv4 host byte order
46  socketAddress_.sin_port = htons(port);// short, network byte order
47 
48  __MOUT__ << "IPAddress: " << IPAddress << " port: " << port << " htons: " << socketAddress_.sin_port << std::endl;
49  if(inet_aton(IPAddress.c_str(), &socketAddress_.sin_addr) == 0)
50  {
51  __SS__ << "FATAL: Invalid IP/Port combination. Is it already in use? " <<
52  IPAddress << "/" << port << std::endl;
53  //assert(0); //RAR changed to exception on 8/17/2016
54  __MOUT__ << "\n" << ss.str();
55  throw std::runtime_error(ss.str());
56  }
57 
58  memset(&(socketAddress_.sin_zero), '\0', 8);// zero the rest of the struct
59 }
60 
61 //========================================================================================================================
62 Socket::~Socket(void)
63 {
64  __MOUT__ << "CLOSING THE SOCKET #" << socketNumber_ << " IP: " << IPAddress_ << " port: " << port_ << " htons: " << socketAddress_.sin_port << std::endl;
65  if(socketNumber_ != -1)
66  close(socketNumber_);
67 }
68 
69 //========================================================================================================================
70 void Socket::initialize(void)
71 {
72  __MOUT__ << " htons: " << socketAddress_.sin_port << std::endl;
73  struct addrinfo hints;
74  struct addrinfo* res;
75  int status = 0;
76 
77  // first, load up address structs with getaddrinfo():
78  memset(&hints, 0, sizeof hints);
79  hints.ai_family = AF_INET; // use IPv4 for OtsUDPHardware
80  hints.ai_socktype = SOCK_DGRAM;// SOCK_DGRAM
81  hints.ai_flags = AI_PASSIVE;// fill in my IP for me
82 
83  bool socketInitialized = false;
84  int fromPort = FirstSocketPort;
85  int toPort = LastSocketPort;
86 
87  if(ntohs(socketAddress_.sin_port) != 0)
88  fromPort = toPort = ntohs(socketAddress_.sin_port);
89 
90  std::stringstream port;
91 
92  for(int p=fromPort; p<=toPort && !socketInitialized; p++)
93  {
94  port.str("");
95  port << p;
96  std::cout << __COUT_HDR_FL__ << __LINE__ << "]\tBinding port: " << port.str() << std::endl;
97  socketAddress_.sin_port = htons(p);// short, network byte order
98 
99  if((status = getaddrinfo(NULL, port.str().c_str(), &hints, &res)) != 0)
100  {
101  std::cout << __COUT_HDR_FL__ << __LINE__ << "]\tGetaddrinfo error status: " << status << std::endl;
102  continue;
103  }
104 
105  // make a socket:
106  socketNumber_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
107 
108  std::cout << __COUT_HDR_FL__ << __LINE__ << "]\tSocket Number: " << socketNumber_ << " for port: " << ntohs(socketAddress_.sin_port) << " initialized." << std::endl;
109  // bind it to the port we passed in to getaddrinfo():
110  if(bind(socketNumber_, res->ai_addr, res->ai_addrlen) == -1)
111  {
112  std::cout << __COUT_HDR_FL__ << "Error********Error********Error********Error********Error********Error" << std::endl;
113  std::cout << __COUT_HDR_FL__ << "FAILED BIND FOR PORT: " << port.str() << " ON IP: " << IPAddress_ << std::endl;
114  std::cout << __COUT_HDR_FL__ << "Error********Error********Error********Error********Error********Error" << std::endl;
115  socketNumber_ = 0;
116  }
117  else
118  {
119  std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
120  std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
121  std::cout << __COUT_HDR_FL__ << "SOCKET ON PORT: " << port.str() << " ON IP: " << IPAddress_ << " INITIALIZED OK!" << std::endl;
122  std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
123  std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
124  char yes = '1';
125  setsockopt(socketNumber_,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int));
126  socketInitialized = true;
127  std::cout << __COUT_HDR_FL__ << __LINE__ << "]\tSocket Number: " << socketNumber_ << " for port: " << ntohs(socketAddress_.sin_port) << " initialized." << std::endl;
128  }
129 
130  freeaddrinfo(res); // free the linked-list
131  }
132 
133  if(!socketInitialized)
134  {
135  std::stringstream ss;
136  ss << __COUT_HDR_FL__ << __LINE__ << "FATAL: Socket could not initialize socket." << std::endl;
137  std::cout << ss.str();
138  //throw std::runtime_error(ss.str());
139  }
140 }
141 
142 //========================================================================================================================
143 const struct sockaddr_in& Socket::getSocketAddress(void)
144 {
145  return socketAddress_;
146 }
147