otsdaq  v1_01_04
 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 //========================================================================================================================
29 Socket::Socket(const std::string &IPAddress, unsigned int port)
30 : socketNumber_(-1)
31 , IPAddress_ (IPAddress)
32 , requestedPort_ (port)
33 // maxSocketSize_(maxSocketSize)
34 {
35  __COUT__ << std::endl;
36  //network stuff
37  socketAddress_.sin_family = AF_INET;// use IPv4 host byte order
38  socketAddress_.sin_port = htons(port);// short, network byte order
39 
40  __COUT__ << "IPAddress: " << IPAddress << " port: " << port << " htons: " << socketAddress_.sin_port << std::endl;
41  if(inet_aton(IPAddress.c_str(), &socketAddress_.sin_addr) == 0)
42  {
43  __SS__ << "FATAL: Invalid IP/Port combination. Is it already in use? " <<
44  IPAddress << "/" << port << std::endl;
45  //assert(0); //RAR changed to exception on 8/17/2016
46  __COUT__ << "\n" << ss.str();
47  throw std::runtime_error(ss.str());
48  }
49 
50  memset(&(socketAddress_.sin_zero), '\0', 8);// zero the rest of the struct
51 }
52 
53 //========================================================================================================================
54 //protected constructor
55 Socket::Socket(void)
56 {
57  __SS__ << "ERROR: This method should never be called. This is the protected constructor. There is something wrong in your inheritance scheme!" << std::endl;
58  __COUT__ << "\n" << ss.str();
59 
60  throw std::runtime_error(ss.str());
61 }
62 
63 //========================================================================================================================
64 Socket::~Socket(void)
65 {
66  __COUT__ << "CLOSING THE SOCKET #" << socketNumber_ << " IP: " << IPAddress_ << " port: " << getPort() << " htons: " << socketAddress_.sin_port << std::endl;
67  if(socketNumber_ != -1)
68  close(socketNumber_);
69 }
70 
71 //========================================================================================================================
72 void Socket::initialize(unsigned int socketReceiveBufferSize)
73 {
74  __COUT__ << " htons: " << socketAddress_.sin_port << std::endl;
75  struct addrinfo hints;
76  struct addrinfo* res;
77  int status = 0;
78 
79  // first, load up address structs with getaddrinfo():
80  memset(&hints, 0, sizeof hints);
81  hints.ai_family = AF_INET; // use IPv4 for OtsUDPHardware
82  hints.ai_socktype = SOCK_DGRAM;// SOCK_DGRAM
83  hints.ai_flags = AI_PASSIVE;// fill in my IP for me
84 
85  bool socketInitialized = false;
86  int fromPort = FirstSocketPort;
87  int toPort = LastSocketPort;
88 
89  if(ntohs(socketAddress_.sin_port) != 0)
90  fromPort = toPort = ntohs(socketAddress_.sin_port);
91 
92  std::stringstream port;
93 
94  for(int p=fromPort; p<=toPort && !socketInitialized; p++)
95  {
96  port.str("");
97  port << p;
98  std::cout << __COUT_HDR_FL__ << __LINE__ << "]\tBinding port: " << port.str() << std::endl;
99  socketAddress_.sin_port = htons(p);// short, network byte order
100 
101  if((status = getaddrinfo(NULL, port.str().c_str(), &hints, &res)) != 0)
102  {
103  std::cout << __COUT_HDR_FL__ << __LINE__ << "]\tGetaddrinfo error status: " << status << std::endl;
104  continue;
105  }
106 
107  // make a socket:
108  socketNumber_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
109 
110  std::cout << __COUT_HDR_FL__ << __LINE__ << "]\tSocket Number: " << socketNumber_ << " for port: " << ntohs(socketAddress_.sin_port) << " initialized." << std::endl;
111  // bind it to the port we passed in to getaddrinfo():
112  if(bind(socketNumber_, res->ai_addr, res->ai_addrlen) == -1)
113  {
114  std::cout << __COUT_HDR_FL__ << "Error********Error********Error********Error********Error********Error" << std::endl;
115  std::cout << __COUT_HDR_FL__ << "FAILED BIND FOR PORT: " << port.str() << " ON IP: " << IPAddress_ << std::endl;
116  std::cout << __COUT_HDR_FL__ << "Error********Error********Error********Error********Error********Error" << std::endl;
117  socketNumber_ = 0;
118  }
119  else
120  {
121  std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
122  std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
123  std::cout << __COUT_HDR_FL__ << "SOCKET ON PORT: " << port.str() << " ON IP: " << IPAddress_ << " INITIALIZED OK!" << std::endl;
124  std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
125  std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
126  char yes = '1';
127  setsockopt(socketNumber_,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int));
128  socketInitialized = true;
129  std::cout << __COUT_HDR_FL__ << __LINE__ << "]\tSocket Number: " << socketNumber_ << " for port: " << ntohs(socketAddress_.sin_port) << " initialized." << std::endl;
130  }
131 
132  freeaddrinfo(res); // free the linked-list
133  }
134 
135  if(!socketInitialized)
136  {
137  __SS__ << "FATAL: Socket could not initialize socket. Perhaps it is already in use?" << std::endl;
138  std::cout << ss.str();
139  throw std::runtime_error(ss.str());
140  }
141 
142 
143  if (setsockopt(socketNumber_, SOL_SOCKET, SO_RCVBUF,
144  (char*)&socketReceiveBufferSize,
145  sizeof(socketReceiveBufferSize)) < 0) {
146  __COUT_ERR__ << "Failed to set socket receive size to " <<
147  socketReceiveBufferSize << ". Attempting to revert to default." << std::endl;
148 
149  socketReceiveBufferSize = defaultSocketReceiveSize_;
150  if (setsockopt(socketNumber_, SOL_SOCKET, SO_RCVBUF,
151  (char*)&socketReceiveBufferSize,
152  sizeof(socketReceiveBufferSize)) < 0)
153  {
154  __SS__ << "Failed to set socket receive size to " <<
155  socketReceiveBufferSize << ". Attempting to revert to default." << std::endl;
156  std::cout << ss.str();
157  throw std::runtime_error(ss.str());
158  }
159 
160  }
161 }
162 
163 uint16_t Socket::getPort()
164 {
165  struct sockaddr_in sin;
166  socklen_t len = sizeof(sin);
167  getsockname(socketNumber_, (struct sockaddr *)&sin, &len);
168  return ntohs(sin.sin_port);
169 }
170 
171 //========================================================================================================================
172 const struct sockaddr_in& Socket::getSocketAddress(void)
173 {
174  return socketAddress_;
175 }
176