otsdaq  3.11.00
TCPTransmitterSocket.cc
1 #include "otsdaq/NetworkUtilities/TCPTransmitterSocket.h"
2 #include <string.h>
3 #include <sys/socket.h>
4 #include <unistd.h>
5 #include <stdexcept>
6 #include "otsdaq/NetworkUtilities/TCPPacket.h"
7 // #include <iostream>
8 
9 using namespace ots;
10 
11 //==============================================================================
12 TCPTransmitterSocket::TCPTransmitterSocket(int socketId) : TCPSocket(socketId) {}
13 
14 //==============================================================================
15 TCPTransmitterSocket::~TCPTransmitterSocket(void) {}
16 
17 //==============================================================================
18 void TCPTransmitterSocket::sendPacket(char const* buffer, std::size_t size)
19 {
20  send(TCPPacket::encode(buffer, size));
21 }
22 
23 //==============================================================================
24 void TCPTransmitterSocket::sendPacket(const std::string& buffer)
25 {
26  send(TCPPacket::encode(buffer));
27 }
28 
29 //==============================================================================
30 void TCPTransmitterSocket::send(char const* buffer,
31  std::size_t size,
32  bool forceEmptyPacket)
33 {
34  if(size == 0 && !forceEmptyPacket)
35  {
36  std::cout << __PRETTY_FUNCTION__ << "I am sorry but I won't send an empty packet!"
37  << std::endl;
38  return;
39  }
40  std::size_t totalSent = 0;
41  while(totalSent < size)
42  {
43  ssize_t sentBytes =
44  ::send(getSocketId(), buffer + totalSent, size - totalSent, MSG_NOSIGNAL);
45  if(sentBytes > 0)
46  {
47  totalSent += static_cast<std::size_t>(sentBytes);
48  continue;
49  }
50 
51  if(sentBytes == 0)
52  {
53  throw std::runtime_error("Write: returned 0 bytes, connection may be closed");
54  }
55 
56  switch(errno)
57  {
58  // case EINVAL:
59  // case EBADF:
60  // case ECONNRESET:
61  // case ENXIO:
62  case EPIPE: {
63  // Fatal error. Programming bug
64  throw std::runtime_error(std::string("Write: critical error: ") +
65  strerror(errno));
66  }
67  // case EDQUOT:
68  // case EFBIG:
69  // case EIO:
70  // case ENETDOWN:
71  // case ENETUNREACH:
72  case ENOSPC: {
73  // Resource acquisition failure or device error
74  throw std::runtime_error(std::string("Write: resource failure: ") +
75  strerror(errno));
76  }
77  case EINTR:
78  // Interrupted by signal; retry send.
79  continue;
80  case EAGAIN:
81  // Temporary back-pressure; retry send.
82  continue;
83  default: {
84  throw std::runtime_error(std::string("Write: returned -1: ") +
85  strerror(errno));
86  }
87  }
88  }
89 }
90 
91 //==============================================================================
92 void TCPTransmitterSocket::send(const std::string& buffer)
93 {
94  send(&buffer.at(0), buffer.size());
95 }
96 
97 //==============================================================================
98 void TCPTransmitterSocket::send(const std::vector<char>& buffer)
99 {
100  send(&buffer.at(0), buffer.size());
101 }
102 
103 //==============================================================================
104 void TCPTransmitterSocket::send(const std::vector<uint16_t>& buffer)
105 {
106  send((const char*)&buffer.at(0), buffer.size());
107 }
108 
109 //==============================================================================
110 void TCPTransmitterSocket::setSendTimeout(unsigned int timeoutSeconds,
111  unsigned int timeoutMicroSeconds)
112 {
113  struct timeval tv;
114  tv.tv_sec = timeoutSeconds;
115  tv.tv_usec = timeoutMicroSeconds;
116  setsockopt(getSocketId(), SOL_SOCKET, SO_SNDTIMEO, (const char*)&tv, sizeof tv);
117 }
defines used also by OtsConfigurationWizardSupervisor