00001 #include "otsdaq-core/NetworkUtilities/Socket.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00004
00005 #include <iostream>
00006 #include <cassert>
00007 #include <sstream>
00008
00009 #include <unistd.h>
00010 #include <arpa/inet.h>
00011
00012 #include <netdb.h>
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <cstring>
00022
00023
00024 using namespace ots;
00025
00026
00027
00028
00029 Socket::Socket(const std::string &IPAddress, unsigned int port)
00030 : socketNumber_(-1)
00031 , IPAddress_ (IPAddress)
00032 , requestedPort_ (port)
00033
00034 {
00035 __COUT__ << std::endl;
00036
00037 socketAddress_.sin_family = AF_INET;
00038 socketAddress_.sin_port = htons(port);
00039
00040 __COUT__ << "IPAddress: " << IPAddress << " port: " << port << " htons: " << socketAddress_.sin_port << std::endl;
00041 if(inet_aton(IPAddress.c_str(), &socketAddress_.sin_addr) == 0)
00042 {
00043 __SS__ << "FATAL: Invalid IP/Port combination. Is it already in use? " <<
00044 IPAddress << "/" << port << std::endl;
00045
00046 __COUT__ << "\n" << ss.str();
00047 throw std::runtime_error(ss.str());
00048 }
00049
00050 memset(&(socketAddress_.sin_zero), '\0', 8);
00051 }
00052
00053
00054
00055 Socket::Socket(void)
00056 {
00057 __SS__ << "ERROR: This method should never be called. This is the protected constructor. There is something wrong in your inheritance scheme!" << std::endl;
00058 __COUT__ << "\n" << ss.str();
00059
00060 throw std::runtime_error(ss.str());
00061 }
00062
00063
00064 Socket::~Socket(void)
00065 {
00066 __COUT__ << "CLOSING THE SOCKET #" << socketNumber_ << " IP: " << IPAddress_ << " port: " << getPort() << " htons: " << socketAddress_.sin_port << std::endl;
00067 if(socketNumber_ != -1)
00068 close(socketNumber_);
00069 }
00070
00071
00072 void Socket::initialize(unsigned int socketReceiveBufferSize)
00073 {
00074 __COUT__ << " htons: " << socketAddress_.sin_port << std::endl;
00075 struct addrinfo hints;
00076 struct addrinfo* res;
00077 int status = 0;
00078
00079
00080 memset(&hints, 0, sizeof hints);
00081 hints.ai_family = AF_INET;
00082 hints.ai_socktype = SOCK_DGRAM;
00083 hints.ai_flags = AI_PASSIVE;
00084
00085 bool socketInitialized = false;
00086 int fromPort = FirstSocketPort;
00087 int toPort = LastSocketPort;
00088
00089 if(ntohs(socketAddress_.sin_port) != 0)
00090 fromPort = toPort = ntohs(socketAddress_.sin_port);
00091
00092 std::stringstream port;
00093
00094 for(int p=fromPort; p<=toPort && !socketInitialized; p++)
00095 {
00096 port.str("");
00097 port << p;
00098 std::cout << __COUT_HDR_FL__ << __LINE__ << "]\tBinding port: " << port.str() << std::endl;
00099 socketAddress_.sin_port = htons(p);
00100
00101 if((status = getaddrinfo(NULL, port.str().c_str(), &hints, &res)) != 0)
00102 {
00103 std::cout << __COUT_HDR_FL__ << __LINE__ << "]\tGetaddrinfo error status: " << status << std::endl;
00104 continue;
00105 }
00106
00107
00108 socketNumber_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
00109
00110 std::cout << __COUT_HDR_FL__ << __LINE__ << "]\tSocket Number: " << socketNumber_ << " for port: " << ntohs(socketAddress_.sin_port) << " initialized." << std::endl;
00111
00112 if(bind(socketNumber_, res->ai_addr, res->ai_addrlen) == -1)
00113 {
00114 std::cout << __COUT_HDR_FL__ << "Error********Error********Error********Error********Error********Error" << std::endl;
00115 std::cout << __COUT_HDR_FL__ << "FAILED BIND FOR PORT: " << port.str() << " ON IP: " << IPAddress_ << std::endl;
00116 std::cout << __COUT_HDR_FL__ << "Error********Error********Error********Error********Error********Error" << std::endl;
00117 socketNumber_ = 0;
00118 }
00119 else
00120 {
00121 std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
00122 std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
00123 std::cout << __COUT_HDR_FL__ << "SOCKET ON PORT: " << port.str() << " ON IP: " << IPAddress_ << " INITIALIZED OK!" << std::endl;
00124 std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
00125 std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
00126 char yes = '1';
00127 setsockopt(socketNumber_,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int));
00128 socketInitialized = true;
00129 std::cout << __COUT_HDR_FL__ << __LINE__ << "]\tSocket Number: " << socketNumber_ << " for port: " << ntohs(socketAddress_.sin_port) << " initialized." << std::endl;
00130 }
00131
00132 freeaddrinfo(res);
00133 }
00134
00135 if(!socketInitialized)
00136 {
00137 __SS__ << "FATAL: Socket could not initialize socket. Perhaps it is already in use?" << std::endl;
00138 std::cout << ss.str();
00139 throw std::runtime_error(ss.str());
00140 }
00141
00142
00143 if (setsockopt(socketNumber_, SOL_SOCKET, SO_RCVBUF,
00144 (char*)&socketReceiveBufferSize,
00145 sizeof(socketReceiveBufferSize)) < 0) {
00146 __COUT_ERR__ << "Failed to set socket receive size to " <<
00147 socketReceiveBufferSize << ". Attempting to revert to default." << std::endl;
00148
00149 socketReceiveBufferSize = defaultSocketReceiveSize_;
00150 if (setsockopt(socketNumber_, SOL_SOCKET, SO_RCVBUF,
00151 (char*)&socketReceiveBufferSize,
00152 sizeof(socketReceiveBufferSize)) < 0)
00153 {
00154 __SS__ << "Failed to set socket receive size to " <<
00155 socketReceiveBufferSize << ". Attempting to revert to default." << std::endl;
00156 std::cout << ss.str();
00157 throw std::runtime_error(ss.str());
00158 }
00159
00160 }
00161 }
00162
00163 uint16_t Socket::getPort()
00164 {
00165 struct sockaddr_in sin;
00166 socklen_t len = sizeof(sin);
00167 getsockname(socketNumber_, (struct sockaddr *)&sin, &len);
00168 return ntohs(sin.sin_port);
00169 }
00170
00171
00172 const struct sockaddr_in& Socket::getSocketAddress(void)
00173 {
00174 return socketAddress_;
00175 }
00176