1 #include "otsdaq-core/NetworkUtilities/TCPSocket.h"
2 #include "artdaq-core/Utilities/TimeUtils.hh"
3 #include "otsdaq-core/Macros/CoutMacros.h"
4 #include "otsdaq-core/MessageFacility/MessageFacility.h"
10 #include <arpa/inet.h>
29 TCPSocket::TCPSocket(
const std::string& senderHost,
30 unsigned int senderPort,
31 int receiveBufferSize)
34 , TCPSocketNumber_(-1)
37 , bufferSize_(receiveBufferSize)
43 TCPSocket::TCPSocket(
unsigned int listenPort,
int sendBufferSize)
45 , TCPSocketNumber_(-1)
48 , bufferSize_(sendBufferSize)
51 TCPSocketNumber_ = TCP_listen_fd(listenPort, bufferSize_);
56 TCPSocket::TCPSocket(
void)
58 __SS__ <<
"ERROR: This method should never be called. This is the protected "
59 "constructor. There is something wrong in your inheritance scheme!"
61 __COUT__ <<
"\n" << ss.str();
67 TCPSocket::~TCPSocket(
void)
69 __COUT__ <<
"CLOSING THE TCPSocket #" << TCPSocketNumber_ <<
" IP: " << host_
70 <<
" port: " << port_ << std::endl;
71 if(TCPSocketNumber_ != -1)
72 close(TCPSocketNumber_);
78 void TCPSocket::connect(
double tmo_s)
80 auto start = std::chrono::steady_clock::now();
83 while(SendSocket_ == -1 && artdaq::TimeUtils::GetElapsedTime(start) < tmo_s)
86 socklen_t arglen =
sizeof(addr);
87 SendSocket_ = accept(TCPSocketNumber_, (
struct sockaddr*)&addr, &arglen);
96 auto sts = read(SendSocket_, &m,
sizeof(MagicPacket));
97 if(!checkMagicPacket(m) || sts !=
sizeof(MagicPacket))
107 while(TCPSocketNumber_ == -1 && artdaq::TimeUtils::GetElapsedTime(start) < tmo_s)
109 TCPSocketNumber_ = TCPConnect(host_.c_str(), port_, 0, O_NONBLOCK);
110 if(TCPSocketNumber_ == -1)
116 auto m = makeMagicPacket(port_);
117 auto sts = ::send(TCPSocketNumber_, &m,
sizeof(MagicPacket), 0);
118 if(sts !=
sizeof(MagicPacket))
121 close(TCPSocketNumber_);
122 TCPSocketNumber_ = -1;
129 int TCPSocket::send(
const uint8_t* data,
size_t size)
131 std::unique_lock<std::mutex> lk(socketMutex_);
132 if(SendSocket_ == -1)
136 if(SendSocket_ == -1)
143 while(offset < size && sts > 0)
145 auto thisSize = size - offset > chunkSize_ ? chunkSize_ : size - offset;
147 sts = ::send(SendSocket_, data + offset, thisSize, 0);
150 if(static_cast<size_t>(sts) != size - offset &&
151 static_cast<size_t>(sts) < chunkSize_)
160 __COUT__ <<
"Error writing buffer for port " << port_ <<
": " << strerror(errno)
168 int TCPSocket::send(
const std::string& buffer)
170 return send(reinterpret_cast<const uint8_t*>(buffer.c_str()), buffer.size());
174 int TCPSocket::send(
const std::vector<uint16_t>& buffer)
176 return send(reinterpret_cast<const uint8_t*>(&buffer[0]),
177 buffer.size() *
sizeof(uint16_t));
181 int TCPSocket::send(
const std::vector<uint32_t>& buffer)
183 return send(reinterpret_cast<const uint8_t*>(&buffer[0]),
184 buffer.size() *
sizeof(uint32_t));
191 int TCPSocket::receive(uint8_t* buffer,
192 unsigned int timeoutSeconds,
193 unsigned int timeoutUSeconds)
196 std::unique_lock<std::mutex> lk(socketMutex_);
198 if(TCPSocketNumber_ == -1)
201 if(TCPSocketNumber_ == -1)
206 struct timeval timeout;
207 timeout.tv_sec = timeoutSeconds;
208 timeout.tv_usec = timeoutUSeconds;
212 FD_SET(TCPSocketNumber_, &fdSet);
213 select(TCPSocketNumber_ + 1, &fdSet, 0, 0, &timeout);
215 if(FD_ISSET(TCPSocketNumber_, &fdSet))
218 if((sts = read(TCPSocketNumber_, buffer, chunkSize_)) == -1)
220 __COUT__ <<
"Error reading buffer from: " << host_ <<
":" << port_
237 int TCPSocket::receive(std::string& buffer,
238 unsigned int timeoutSeconds,
239 unsigned int timeoutUSeconds)
241 buffer.resize(chunkSize_);
243 receive(reinterpret_cast<uint8_t*>(&buffer[0]), timeoutSeconds, timeoutUSeconds);
256 int TCPSocket::receive(std::vector<uint32_t>& buffer,
257 unsigned int timeoutSeconds,
258 unsigned int timeoutUSeconds)
260 buffer.resize(chunkSize_ /
sizeof(uint32_t));
262 receive(reinterpret_cast<uint8_t*>(&buffer[0]), timeoutSeconds, timeoutUSeconds);