$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "otsdaq-core/NetworkUtilities/ReceiverSocket.h" 00002 #include "otsdaq-core/Macros/CoutMacros.h" 00003 #include "otsdaq-core/MessageFacility/MessageFacility.h" 00004 #include "otsdaq-core/NetworkUtilities/NetworkConverters.h" 00005 00006 #include <iomanip> /* for setfill */ 00007 #include <iostream> 00008 #include <sstream> 00009 00010 #include <arpa/inet.h> 00011 #include <sys/time.h> 00012 00013 using namespace ots; 00014 00015 //======================================================================================================================== 00016 ReceiverSocket::ReceiverSocket(std::string IPAddress, unsigned int port) 00017 : Socket(IPAddress, port) 00018 , addressLength_(sizeof(fromAddress_)) 00019 , numberOfBytes_(0) 00020 , readCounter_(0) 00021 { 00022 __COUT__ << "ReceiverSocket constructor " << IPAddress << ":" << port << __E__; 00023 } 00024 00025 //======================================================================================================================== 00026 // protected constructor 00027 ReceiverSocket::ReceiverSocket(void) 00028 : addressLength_(sizeof(fromAddress_)), numberOfBytes_(0), readCounter_(0) 00029 { 00030 __COUT__ << "ReceiverSocket constructor" << __E__; 00031 } 00032 00033 //======================================================================================================================== 00034 ReceiverSocket::~ReceiverSocket(void) {} 00035 00036 //======================================================================================================================== 00037 int ReceiverSocket::receive(std::string& buffer, 00038 unsigned int timeoutSeconds, 00039 unsigned int timeoutUSeconds, 00040 bool verbose) 00041 { 00042 return receive( 00043 buffer, dummyIPAddress_, dummyPort_, timeoutSeconds, timeoutUSeconds, verbose); 00044 } 00045 00046 //======================================================================================================================== 00047 // receive ~~ 00048 // returns 0 on success, -1 on failure 00049 // NOTE: must call Socket::initialize before receiving! 00050 int ReceiverSocket::receive(std::string& buffer, 00051 unsigned long& fromIPAddress, 00052 unsigned short& fromPort, 00053 unsigned int timeoutSeconds, 00054 unsigned int timeoutUSeconds, 00055 bool verbose) 00056 { 00057 // lockout other receivers for the remainder of the scope 00058 std::lock_guard<std::mutex> lock(receiveMutex_); 00059 00060 // set timeout period for select() 00061 timeout_.tv_sec = timeoutSeconds; 00062 timeout_.tv_usec = timeoutUSeconds; 00063 00064 FD_ZERO(&fileDescriptor_); 00065 FD_SET(socketNumber_, &fileDescriptor_); 00066 select(socketNumber_ + 1, &fileDescriptor_, 0, 0, &timeout_); 00067 00068 if(FD_ISSET(socketNumber_, &fileDescriptor_)) 00069 { 00070 buffer.resize(maxSocketSize_); // NOTE: this is inexpensive according to 00071 // Lorenzo/documentation in C++11 (only increases 00072 // size once and doesn't decrease size) 00073 if((numberOfBytes_ = recvfrom(socketNumber_, 00074 &buffer[0], 00075 maxSocketSize_, 00076 0, 00077 (struct sockaddr*)&fromAddress_, 00078 &addressLength_)) == -1) 00079 { 00080 __COUT__ << "At socket with IPAddress: " << getIPAddress() 00081 << " port: " << getPort() << std::endl; 00082 __SS__ << "Error reading buffer from\tIP:\t"; 00083 std::string fromIP = inet_ntoa(fromAddress_.sin_addr); 00084 fromIPAddress = fromAddress_.sin_addr.s_addr; 00085 fromPort = fromAddress_.sin_port; 00086 for(int i = 0; i < 4; i++) 00087 { 00088 ss << ((fromIPAddress << (i * 8)) & 0xff); 00089 if(i < 3) 00090 ss << "."; 00091 } 00092 ss << "\tPort\t" << ntohs(fromPort) << " IP " << fromIP << std::endl; 00093 __COUT__ << "\n" << ss.str(); 00094 return -1; 00095 } 00096 // char address[INET_ADDRSTRLEN]; 00097 // inet_ntop(AF_INET, &(fromAddress.sin_addr), address, INET_ADDRSTRLEN); 00098 fromIPAddress = fromAddress_.sin_addr.s_addr; 00099 fromPort = fromAddress_.sin_port; 00100 00101 //__COUT__ << __PRETTY_FUNCTION__ << "IP: " << std::hex << fromIPAddress << 00102 // std::dec << " port: " << fromPort << std::endl; 00103 //__COUT__ << "Socket Number: " << socketNumber_ << " number of bytes: " << 00104 // nOfBytes << std::endl; gettimeofday(&tvend,NULL); 00105 //__COUT__ << "started at" << tvbegin.tv_sec << ":" <<tvbegin.tv_usec << 00106 // std::endl; 00107 //__COUT__ << "ended at" << tvend.tv_sec << ":" <<tvend.tv_usec << std::endl; 00108 00109 // NOTE: this is inexpensive according to Lorenzo/documentation in C++11 (only 00110 // increases size once and doesn't decrease size) 00111 buffer.resize(numberOfBytes_); 00112 readCounter_ = 0; 00113 00114 if(verbose) // debug 00115 { 00116 std::string fromIP = inet_ntoa(fromAddress_.sin_addr); 00117 00118 __COUT__ << "Receiving " 00119 << " at: " << getIPAddress() << ":" << getPort() 00120 << " from: " << fromIP; 00121 std::cout << ":" << ntohs(fromPort) << " size: " << buffer.size() 00122 << std::endl; 00123 00124 // std::stringstream ss; 00125 // ss << "\tRx"; 00126 // uint32_t begin = 0; 00127 // for(uint32_t i=begin; i<buffer.size(); i++) 00128 // { 00129 // if(i==begin+2) ss << ":::"; 00130 // else if(i==begin+10) ss << ":::"; 00131 // ss << std::setfill('0') << std::setw(2) << std::hex << 00132 //(((int16_t) buffer[i]) &0xFF) << "-" << std::dec; 00133 // } 00134 // ss << std::endl; 00135 // std::cout << ss.str(); 00136 } 00137 } 00138 else 00139 { 00140 ++readCounter_; 00141 00142 if(verbose) 00143 __COUT__ << "No new messages for " << timeoutSeconds + timeoutUSeconds / 1000. 00144 << "s (Total " 00145 << readCounter_ * (timeoutSeconds + timeoutUSeconds / 1000.) 00146 << "s). Read request timed out receiving on " 00147 << " " << getIPAddress() << ":" << getPort() << std::endl; 00148 return -1; 00149 } 00150 00151 return 0; 00152 } 00153 00154 //======================================================================================================================== 00155 int ReceiverSocket::receive(std::vector<uint32_t>& buffer, 00156 unsigned int timeoutSeconds, 00157 unsigned int timeoutUSeconds, 00158 bool verbose) 00159 { 00160 return receive( 00161 buffer, dummyIPAddress_, dummyPort_, timeoutSeconds, timeoutUSeconds, verbose); 00162 } 00163 00164 //======================================================================================================================== 00165 // receive ~~ 00166 // returns 0 on success, -1 on failure 00167 // NOTE: must call Socket::initialize before receiving! 00168 int ReceiverSocket::receive(std::vector<uint32_t>& buffer, 00169 unsigned long& fromIPAddress, 00170 unsigned short& fromPort, 00171 unsigned int timeoutSeconds, 00172 unsigned int timeoutUSeconds, 00173 bool verbose) 00174 { 00175 // lockout other receivers for the remainder of the scope 00176 std::lock_guard<std::mutex> lock(receiveMutex_); 00177 00178 // set timeout period for select() 00179 timeout_.tv_sec = timeoutSeconds; 00180 timeout_.tv_usec = timeoutUSeconds; 00181 00182 FD_ZERO(&fileDescriptor_); 00183 FD_SET(socketNumber_, &fileDescriptor_); 00184 select(socketNumber_ + 1, &fileDescriptor_, 0, 0, &timeout_); 00185 __COUT__ << "Is this a successful reeeaaad???" << std::endl; 00186 00187 if(FD_ISSET(socketNumber_, &fileDescriptor_)) 00188 { 00189 buffer.resize(maxSocketSize_ / sizeof(uint32_t)); // NOTE: this is inexpensive 00190 // according to 00191 // Lorezno/documentation in 00192 // C++11 (only increases size 00193 // once and doesn't decrease 00194 // size) 00195 if((numberOfBytes_ = recvfrom(socketNumber_, 00196 &buffer[0], 00197 maxSocketSize_, 00198 0, 00199 (struct sockaddr*)&fromAddress_, 00200 &addressLength_)) == -1) 00201 { 00202 __COUT__ << "At socket with IPAddress: " << getIPAddress() 00203 << " port: " << getPort() << std::endl; 00204 __SS__ << "Error reading buffer from\tIP:\t"; 00205 for(int i = 0; i < 4; i++) 00206 { 00207 ss << ((fromIPAddress << (i * 8)) & 0xff); 00208 if(i < 3) 00209 ss << "."; 00210 } 00211 ss << "\tPort\t" << fromPort << std::endl; 00212 __COUT__ << "\n" << ss.str(); 00213 return -1; 00214 } 00215 // char address[INET_ADDRSTRLEN]; 00216 // inet_ntop(AF_INET, &(fromAddress.sin_addr), address, INET_ADDRSTRLEN); 00217 fromIPAddress = fromAddress_.sin_addr.s_addr; 00218 fromPort = fromAddress_.sin_port; 00219 00220 //__COUT__ << __PRETTY_FUNCTION__ << "IP: " << std::hex << fromIPAddress << 00221 // std::dec << " port: " << fromPort << std::endl; 00222 //__COUT__ << "Socket Number: " << socketNumber_ << " number of bytes: " << 00223 // nOfBytes << std::endl; gettimeofday(&tvend,NULL); 00224 //__COUT__ << "started at" << tvbegin.tv_sec << ":" <<tvbegin.tv_usec << 00225 // std::endl; 00226 //__COUT__ << "ended at" << tvend.tv_sec << ":" <<tvend.tv_usec << std::endl; 00227 00228 // NOTE: this is inexpensive according to Lorenzo/documentation in C++11 (only 00229 // increases size once and doesn't decrease size) 00230 buffer.resize(numberOfBytes_ / sizeof(uint32_t)); 00231 readCounter_ = 0; 00232 } 00233 else 00234 { 00235 ++readCounter_; 00236 struct sockaddr_in sin; 00237 socklen_t len = sizeof(sin); 00238 getsockname(socketNumber_, (struct sockaddr*)&sin, &len); 00239 00240 if(verbose) 00241 __COUT__ << __COUT_HDR_FL__ << "No new messages for " 00242 << timeoutSeconds + timeoutUSeconds / 1000. << "s (Total " 00243 << readCounter_ * (timeoutSeconds + timeoutUSeconds / 1000.) 00244 << "s). Read request timed out for port: " << ntohs(sin.sin_port) 00245 << std::endl; 00246 return -1; 00247 } 00248 __COUT__ << "This a successful reeeaaad" << std::endl; 00249 return 0; 00250 }