$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "otsdaq-core/NetworkUtilities/Socket.h" 00002 #include "otsdaq-core/Macros/CoutMacros.h" 00003 #include "otsdaq-core/MessageFacility/MessageFacility.h" 00004 00005 #include <cassert> 00006 #include <iostream> 00007 #include <sstream> 00008 00009 #include <arpa/inet.h> 00010 #include <unistd.h> 00011 //#include <sys/socket.h> 00012 #include <netdb.h> 00013 //#include <ifaddrs.h> 00014 //#include <sys/ioctl.h> 00015 //#if defined(SIOCGIFHWADDR) 00016 //#include <net/if.h> 00017 //#else 00018 //#include <net/if_dl.h> 00019 //#endif 00020 //#include <cstdlib> 00021 #include <cstring> 00022 //#include <cstdio> 00023 00024 using namespace ots; 00025 00026 //======================================================================================================================== 00027 Socket::Socket(const std::string& IPAddress, unsigned int port) 00028 : socketNumber_(-1), IPAddress_(IPAddress), requestedPort_(port) 00029 // maxSocketSize_(maxSocketSize) 00030 { 00031 __COUT__ << "Socket constructor " << IPAddress << ":" << port << __E__; 00032 00033 if(port >= (1 << 16)) 00034 { 00035 __SS__ << "FATAL: Invalid Port " << port << ". Max port number is " 00036 << (1 << 16) - 1 << "." << std::endl; 00037 // assert(0); //RAR changed to exception on 8/17/2016 00038 __COUT_ERR__ << "\n" << ss.str(); 00039 __SS_THROW__; 00040 } 00041 00042 // network stuff 00043 socketAddress_.sin_family = AF_INET; // use IPv4 host byte order 00044 socketAddress_.sin_port = htons(port); // short, network byte order 00045 00046 __COUT__ << "IPAddress: " << IPAddress << " port: " << port 00047 << " htons: " << socketAddress_.sin_port << std::endl; 00048 00049 if(inet_aton(IPAddress.c_str(), &socketAddress_.sin_addr) == 0) 00050 { 00051 __SS__ << "FATAL: Invalid IP:Port combination. Please verify... " << IPAddress 00052 << ":" << port << std::endl; 00053 // assert(0); //RAR changed to exception on 8/17/2016 00054 __COUT_ERR__ << "\n" << ss.str(); 00055 __SS_THROW__; 00056 } 00057 00058 memset(&(socketAddress_.sin_zero), '\0', 8); // zero the rest of the struct 00059 00060 __COUT__ << "Constructed socket for port " << ntohs(socketAddress_.sin_port) << "=" 00061 << getPort() << " htons: " << socketAddress_.sin_port << std::endl; 00062 } 00063 00064 //======================================================================================================================== 00065 // protected constructor 00066 Socket::Socket(void) 00067 { 00068 __SS__ << "ERROR: This method should never be called. This is the protected " 00069 "constructor. There is something wrong in your inheritance scheme!" 00070 << std::endl; 00071 __COUT_ERR__ << "\n" << ss.str(); 00072 00073 __SS_THROW__; 00074 } 00075 00076 //======================================================================================================================== 00077 Socket::~Socket(void) 00078 { 00079 __COUT__ << "CLOSING THE SOCKET #" << socketNumber_ << " IP: " << IPAddress_ 00080 << " port: " << getPort() << " htons: " << socketAddress_.sin_port 00081 << std::endl; 00082 if(socketNumber_ != -1) 00083 close(socketNumber_); 00084 } 00085 00086 //======================================================================================================================== 00087 void Socket::initialize(unsigned int socketReceiveBufferSize) 00088 { 00089 __COUT__ << "Initializing port " << ntohs(socketAddress_.sin_port) 00090 << " htons: " << socketAddress_.sin_port << std::endl; 00091 struct addrinfo hints; 00092 struct addrinfo* res; 00093 int status = 0; 00094 00095 // first, load up address structs with getaddrinfo(): 00096 memset(&hints, 0, sizeof hints); 00097 hints.ai_family = AF_INET; // use IPv4 for OtsUDPHardware 00098 hints.ai_socktype = SOCK_DGRAM; // SOCK_DGRAM 00099 hints.ai_flags = AI_PASSIVE; // fill in my IP for me 00100 00101 bool socketInitialized = false; 00102 int fromPort = FirstSocketPort; 00103 int toPort = LastSocketPort; 00104 00105 if(ntohs(socketAddress_.sin_port) != 0) 00106 fromPort = toPort = ntohs(socketAddress_.sin_port); 00107 00108 std::stringstream port; 00109 00110 for(int p = fromPort; p <= toPort && !socketInitialized; p++) 00111 { 00112 port.str(""); 00113 port << p; 00114 __COUT__ << "]\tBinding port: " << port.str() << std::endl; 00115 socketAddress_.sin_port = htons(p); // short, network byte order 00116 00117 if((status = getaddrinfo(NULL, port.str().c_str(), &hints, &res)) != 0) 00118 { 00119 __COUT__ << "]\tGetaddrinfo error status: " << status << std::endl; 00120 continue; 00121 } 00122 00123 // make a socket: 00124 socketNumber_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 00125 00126 __COUT__ << "]\tSocket Number: " << socketNumber_ 00127 << " for port: " << ntohs(socketAddress_.sin_port) << " initialized." 00128 << std::endl; 00129 // bind it to the port we passed in to getaddrinfo(): 00130 if(bind(socketNumber_, res->ai_addr, res->ai_addrlen) == -1) 00131 { 00132 std::cout << __COUT_HDR_FL__ 00133 << "Error********Error********Error********Error********Error******" 00134 "**Error" 00135 << std::endl; 00136 std::cout << __COUT_HDR_FL__ << "FAILED BIND FOR PORT: " << port.str() 00137 << " ON IP: " << IPAddress_ << std::endl; 00138 std::cout << __COUT_HDR_FL__ 00139 << "Error********Error********Error********Error********Error******" 00140 "**Error" 00141 << std::endl; 00142 socketNumber_ = 0; 00143 } 00144 else 00145 { 00146 std::cout << __COUT_HDR_FL__ 00147 << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):" 00148 "):):):)" 00149 << std::endl; 00150 std::cout << __COUT_HDR_FL__ 00151 << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):" 00152 "):):):)" 00153 << std::endl; 00154 std::cout << __COUT_HDR_FL__ << "SOCKET ON PORT: " << port.str() 00155 << " ON IP: " << IPAddress_ << " INITIALIZED OK!" << std::endl; 00156 std::cout << __COUT_HDR_FL__ 00157 << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):" 00158 "):):):)" 00159 << std::endl; 00160 std::cout << __COUT_HDR_FL__ 00161 << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):" 00162 "):):):)" 00163 << std::endl; 00164 char yes = '1'; 00165 setsockopt(socketNumber_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); 00166 socketInitialized = true; 00167 __COUT__ << "]\tSocket Number: " << socketNumber_ 00168 << " for port: " << ntohs(socketAddress_.sin_port) << " initialized." 00169 << std::endl; 00170 } 00171 00172 freeaddrinfo(res); // free the linked-list 00173 } 00174 00175 if(!socketInitialized) 00176 { 00177 __SS__ << "FATAL: Socket could not initialize socket (IP=" << IPAddress_ 00178 << ", Port=" << ntohs(socketAddress_.sin_port) 00179 << "). Perhaps it is already in use?" << std::endl; 00180 std::cout << ss.str(); 00181 __SS_THROW__; 00182 } 00183 00184 __COUT__ << "Setting socket receive buffer size = " << socketReceiveBufferSize 00185 << " 0x" << std::hex << socketReceiveBufferSize << std::dec << __E__; 00186 if(setsockopt(socketNumber_, 00187 SOL_SOCKET, 00188 SO_RCVBUF, 00189 (char*)&socketReceiveBufferSize, 00190 sizeof(socketReceiveBufferSize)) < 0) 00191 { 00192 __COUT_ERR__ << "Failed to set socket receive size to " << socketReceiveBufferSize 00193 << ". Attempting to revert to default." << std::endl; 00194 00195 socketReceiveBufferSize = defaultSocketReceiveSize_; 00196 00197 __COUT__ << "Setting socket receive buffer size = " << socketReceiveBufferSize 00198 << " 0x" << std::hex << socketReceiveBufferSize << std::dec << __E__; 00199 if(setsockopt(socketNumber_, 00200 SOL_SOCKET, 00201 SO_RCVBUF, 00202 (char*)&socketReceiveBufferSize, 00203 sizeof(socketReceiveBufferSize)) < 0) 00204 { 00205 __SS__ << "Failed to set socket receive size to " << socketReceiveBufferSize 00206 << ". Attempting to revert to default." << std::endl; 00207 std::cout << ss.str(); 00208 __SS_THROW__; 00209 } 00210 } 00211 } 00212 00213 uint16_t Socket::getPort() 00214 { 00215 return ntohs(socketAddress_.sin_port); 00216 00217 // //else extract from socket 00218 // struct sockaddr_in sin; 00219 // socklen_t len = sizeof(sin); 00220 // getsockname(socketNumber_, (struct sockaddr *)&sin, &len); 00221 // return ntohs(sin.sin_port); 00222 } 00223 00224 //======================================================================================================================== 00225 const struct sockaddr_in& Socket::getSocketAddress(void) { return socketAddress_; }