1 #include "otsdaq-core/NetworkUtilities/TCPSocket.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
10 #include <arpa/inet.h>
28 TCPSocket::TCPSocket(
const std::string &senderHost,
unsigned int senderPort,
int receiveBufferSize)
31 , TCPSocketNumber_(-1)
34 , bufferSize_(receiveBufferSize)
38 TCPSocket::TCPSocket(
unsigned int listenPort,
int sendBufferSize)
40 , TCPSocketNumber_(-1)
43 , bufferSize_(sendBufferSize)
46 TCPSocketNumber_ = TCP_listen_fd(listenPort, 0);
50 socklen_t lenlen =
sizeof(len);
52 auto sts = getsockopt(TCPSocketNumber_, SOL_SOCKET, SO_SNDBUF, &len, &lenlen);
53 TRACE(3,
"TCPConnect SNDBUF initial: %d sts/errno=%d/%d lenlen=%d", len, sts, errno, lenlen);
55 sts = setsockopt(TCPSocketNumber_, SOL_SOCKET, SO_SNDBUF, &len, lenlen);
57 TRACE(0,
"Error with setsockopt SNDBUF %d", errno);
59 sts = getsockopt(TCPSocketNumber_, SOL_SOCKET, SO_SNDBUF, &len, &lenlen);
60 if (len < (bufferSize_ * 2))
61 TRACE(1,
"SNDBUF %d not expected (%d) sts/errno=%d/%d"
62 , len, bufferSize_, sts, errno);
64 TRACE(3,
"SNDBUF %d sts/errno=%d/%d", len, sts, errno);
70 TCPSocket::TCPSocket(
void)
72 __SS__ <<
"ERROR: This method should never be called. This is the protected constructor. There is something wrong in your inheritance scheme!" << std::endl;
73 __COUT__ <<
"\n" << ss.str();
75 throw std::runtime_error(ss.str());
79 TCPSocket::~TCPSocket(
void)
81 __COUT__ <<
"CLOSING THE TCPSocket #" << TCPSocketNumber_ <<
" IP: " << host_ <<
" port: " << port_ << std::endl;
82 if (TCPSocketNumber_ != -1)
83 close(TCPSocketNumber_);
84 if (SendSocket_ != -1)
88 void TCPSocket::connect()
93 socklen_t arglen =
sizeof(addr);
94 SendSocket_ = accept(TCPSocketNumber_, (
struct sockaddr *)&addr, &arglen);
96 if (SendSocket_ == -1)
103 auto sts = read(SendSocket_, &m,
sizeof(MagicPacket));
104 if (!checkMagicPacket(m) || sts !=
sizeof(MagicPacket))
112 TCPSocketNumber_ = TCPConnect(host_.c_str(), port_, 0, O_NONBLOCK);
113 auto m = makeMagicPacket(port_);
114 auto sts = ::send(TCPSocketNumber_, &m,
sizeof(MagicPacket), 0);
115 if (sts !=
sizeof(MagicPacket))
124 int TCPSocket::send(
const uint8_t* data,
size_t size)
126 std::unique_lock<std::mutex> lk(socketMutex_);
127 if (SendSocket_ == -1)
135 while (offset < size && sts > 0)
137 auto thisSize = size - offset > chunkSize_ ? chunkSize_ : size - offset;
139 sts = ::send(SendSocket_, data + offset, thisSize, 0);
142 if (static_cast<size_t>(sts) != size - offset && static_cast<size_t>(sts) < chunkSize_)
151 __COUT__ <<
"Error writing buffer for port " << port_ <<
": " << strerror(errno) << std::endl;
158 int TCPSocket::send(
const std::string& buffer)
160 return send(reinterpret_cast<const uint8_t*>(buffer.c_str()), buffer.size());
164 int TCPSocket::send(
const std::vector<uint16_t>& buffer)
166 return send(reinterpret_cast<const uint8_t*>(&buffer[0]), buffer.size() *
sizeof(uint16_t));
170 int TCPSocket::send(
const std::vector<uint32_t>& buffer)
172 return send(reinterpret_cast<const uint8_t*>(&buffer[0]), buffer.size() *
sizeof(uint32_t));
179 int TCPSocket::receive(uint8_t* buffer,
unsigned int timeoutSeconds,
unsigned int timeoutUSeconds)
182 std::unique_lock<std::mutex> lk(socketMutex_);
184 if (TCPSocketNumber_ == -1)
190 struct timeval timeout;
191 timeout.tv_sec = timeoutSeconds;
192 timeout.tv_usec = timeoutUSeconds;
196 FD_SET(TCPSocketNumber_, &fdSet);
197 select(TCPSocketNumber_ + 1, &fdSet, 0, 0, &timeout);
199 if (FD_ISSET(TCPSocketNumber_, &fdSet))
202 if ((sts = read(TCPSocketNumber_, buffer, chunkSize_)) == -1)
204 __COUT__ <<
"Error reading buffer from: " << host_ <<
":" << port_ << std::endl;
219 int TCPSocket::receive(std::string& buffer,
unsigned int timeoutSeconds,
unsigned int timeoutUSeconds)
221 buffer.resize(chunkSize_);
222 auto sts = receive(reinterpret_cast<uint8_t*>(&buffer[0]), timeoutSeconds, timeoutUSeconds);
235 int TCPSocket::receive(std::vector<uint32_t>& buffer,
unsigned int timeoutSeconds,
unsigned int timeoutUSeconds)
237 buffer.resize(chunkSize_ /
sizeof(uint32_t));
238 auto sts = receive(reinterpret_cast<uint8_t*>(&buffer[0]), timeoutSeconds, timeoutUSeconds);