otsdaq  v2_04_02
TCPReceiverSocket.cc
1 #include "otsdaq/NetworkUtilities/TCPReceiverSocket.h"
2 #include <sys/socket.h>
3 #include <unistd.h> //read
4 #include <iostream>
5 #include <sstream>
6 #include <stdexcept>
7 
8 using namespace ots;
9 //========================================================================================================================
10 TCPReceiverSocket::TCPReceiverSocket(int socketId) : TCPSocket(socketId)
11 {
12  fPacket.reset();
13 }
14 
15 //========================================================================================================================
16 TCPReceiverSocket::~TCPReceiverSocket(void) {}
17 
18 //========================================================================================================================
19 std::string TCPReceiverSocket::receivePacket(void)
20 {
21  while(true)
22  {
23  std::string retVal = "";
24  if(fPacket.decode(retVal))
25  return retVal;
26  fPacket += receive<std::string>();
27  }
28 }
29 
30 //========================================================================================================================
31 std::size_t TCPReceiverSocket::receive(char* buffer, std::size_t bufferSize)
32 {
33  // std::cout << __PRETTY_FUNCTION__ << "Receiving Message for socket: " <<
34  // getSocketId() << std::endl;
35  if(getSocketId() == 0)
36  {
37  throw std::logic_error("Bad socket object (this object was moved)");
38  }
39  std::size_t dataRead = ::read(getSocketId(), buffer, bufferSize);
40  if(dataRead == static_cast<std::size_t>(-1))
41  {
42  std::stringstream error;
43  switch(errno)
44  {
45  case EBADF:
46  error
47  << "Socket file descriptor " << getSocketId()
48  << " is not a valid file descriptor or is not open for reading...Errno: "
49  << errno;
50  break;
51  case EFAULT:
52  error << "Buffer is outside your accessible address space...Errno: " << errno;
53  break;
54  case ENXIO:
55  {
56  // Fatal error. Programming bug
57  error << "Read critical error caused by a programming bug...Errno: " << errno;
58  throw std::domain_error(error.str());
59  }
60  case EINTR:
61  // TODO: Check for user interrupt flags.
62  // Beyond the scope of this project
63  // so continue normal operations.
64  error << "The call was interrupted by a signal before any data was "
65  "read...Errno: "
66  << errno;
67  break;
68  case EAGAIN:
69  {
70  // Temporary error.
71  // Simply retry the read.
72  std::cout << __PRETTY_FUNCTION__
73  << "Read returned EAGAIN error which means that the read was "
74  "temporarily broken. If this continues it is a problem because "
75  "I am in a recursive loop!"
76  << std::endl;
77  dataRead = receive(buffer, bufferSize);
78  return dataRead;
79  }
80  case ENOTCONN:
81  {
82  // Connection broken.
83  // Return the data we have available and exit
84  // as if the connection was closed correctly.
85  return dataRead;
86  }
87  default:
88  {
89  error << "Read: returned -1...Errno: " << errno;
90  }
91  }
92  throw std::runtime_error(error.str());
93  }
94  // std::cout << __PRETTY_FUNCTION__ << "Message received with no errors for socket: "
95  // << getSocketId() << std::endl;
96  return dataRead;
97 }