UdpSocket.cpp
Go to the documentation of this file.
1 // -- BEGIN LICENSE BLOCK ----------------------------------------------
20 // -- END LICENSE BLOCK ------------------------------------------------
21 
22 #include <cstring>
23 
25 
26 namespace visionary {
27 
29  : m_socket()
30 {
31  memset(&m_udpAddr, 0, sizeof(m_udpAddr));
32 }
33 
35 {
36  int iResult = 0;
37  long timeoutSeconds = 5L;
38 
39 #ifdef _WIN32
40  //-----------------------------------------------
41  // Initialize Winsock
42  WSADATA wsaData;
43  iResult = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
44  if (iResult != NO_ERROR)
45  {
46  return iResult;
47  }
48 #endif
49 
50  //-----------------------------------------------
51  // Create a receiver socket to receive datagrams
52  m_socket = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
53  if (m_socket == INVALID_SOCKET)
54  {
55  return static_cast<int>(INVALID_SOCKET);
56  }
57 
58  // Set the timeout for the socket to 5 seconds
59 #ifdef _WIN32
60  // On Windows timeout is a DWORD in milliseconds
61  // (https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-setsockopt)
62  long timeoutMs = timeoutSeconds * 1000L;
63  iResult =
64  setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeoutMs, sizeof(timeoutMs));
65 #else
66  struct timeval tv;
67  tv.tv_sec = timeoutSeconds; /* 5 seconds Timeout */
68  tv.tv_usec = 0L; // Not init'ing this can cause strange errors
69  iResult = setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(struct timeval));
70 #endif
71 
72  return iResult;
73 }
74 
75 int UdpSocket::connect(const std::string& hostname, uint16_t port)
76 {
77  int iResult = 0;
78  int trueVal = 1;
79 
80  iResult = initSocket();
81 
82  // Enable UDP broadcast
83  if (iResult >= 0)
84  {
85  //-----------------------------------------------
86  // Bind the socket to any address and the specified port.
87  m_udpAddr.sin_family = AF_INET;
88  m_udpAddr.sin_port = port;
89  m_udpAddr.sin_addr.s_addr = inet_addr(hostname.c_str());
90  iResult =
91  setsockopt(m_socket, SOL_SOCKET, SO_BROADCAST, (const char*)&trueVal, sizeof(trueVal));
92  }
93 
94  return iResult;
95 }
96 
97 int UdpSocket::bindPort(std::uint16_t port)
98 {
99  int iResult = 0;
100 
101  iResult = initSocket();
102 
103  if (iResult >= 0)
104  {
105  // set socket receive buffer size to 512kB
106  int bufferSize = 512 * 1024;
107  int bufferSizeLen = sizeof(bufferSize);
108  iResult = setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (char*)&bufferSize, bufferSizeLen);
109 
110  if (iResult >= 0)
111  {
112  //-----------------------------------------------
113  // Bind socket to given port
114  sockaddr_in saddr;
115  saddr.sin_family = AF_INET;
116  saddr.sin_addr.s_addr = htonl(INADDR_ANY);
117  saddr.sin_port = port;
118  iResult = bind(m_socket, reinterpret_cast<sockaddr*>(&saddr), sizeof(saddr));
119  }
120  }
121  return iResult;
122 }
123 
125 {
126  // Close the socket when finished receiving datagrams
127 #ifdef _WIN32
128  closesocket(m_socket);
129  WSACleanup();
130 #else
131  close(m_socket);
132 #endif
133  m_socket = static_cast<int>(INVALID_SOCKET);
134  return 0;
135 }
136 
137 int UdpSocket::send(const std::vector<std::uint8_t>& buffer)
138 {
139  // send buffer via UDP socket
140  return sendto(m_socket,
141  reinterpret_cast<const char*>(buffer.data()),
142  static_cast<int>(buffer.size()),
143  0,
144  (struct sockaddr*)&m_udpAddr,
145  sizeof(m_udpAddr));
146 }
147 
148 int UdpSocket::recv(std::vector<std::uint8_t>& buffer, std::size_t maxBytesToReceive)
149 {
150  // receive from UDP Socket
151  buffer.resize(maxBytesToReceive);
152  char* pBuffer = reinterpret_cast<char*>(buffer.data());
153 
154  return ::recv(m_socket, pBuffer, static_cast<int>(maxBytesToReceive), 0);
155 }
156 
157 int UdpSocket::read(std::vector<std::uint8_t>& buffer, std::size_t nBytesToReceive)
158 {
159  // receive from TCP Socket
160  buffer.resize(nBytesToReceive);
161  char* pBuffer = reinterpret_cast<char*>(buffer.data());
162 
163  int bytesReceived = 0;
164  while (nBytesToReceive > 0)
165  {
166  bytesReceived = ::recv(m_socket, pBuffer, static_cast<int>(nBytesToReceive), 0);
167 
168  if (bytesReceived == SOCKET_ERROR || bytesReceived == 0)
169  {
170  return false;
171  }
172  pBuffer += bytesReceived;
173  nBytesToReceive -= bytesReceived;
174  }
175  pBuffer = NULL;
176  return bytesReceived;
177 }
178 
179 } // namespace visionary
visionary::UdpSocket::read
int read(std::vector< std::uint8_t > &buffer, std::size_t nBytesToReceive) override
Definition: UdpSocket.cpp:157
INVALID_SOCKET
#define INVALID_SOCKET
Definition: TcpSocket.h:44
visionary::UdpSocket::send
int send(const std::vector< std::uint8_t > &buffer) override
Definition: UdpSocket.cpp:137
visionary
Definition: AuthenticationLegacy.h:25
UdpSocket.h
SOCKET_ERROR
#define SOCKET_ERROR
Definition: TcpSocket.h:45
visionary::UdpSocket::recv
int recv(std::vector< std::uint8_t > &buffer, std::size_t maxBytesToReceive) override
Definition: UdpSocket.cpp:148
visionary::UdpSocket::UdpSocket
UdpSocket()
Definition: UdpSocket.cpp:28
visionary::UdpSocket::bindPort
int bindPort(std::uint16_t port)
Definition: UdpSocket.cpp:97
visionary::UdpSocket::m_socket
SOCKET m_socket
Definition: UdpSocket.h:64
visionary::UdpSocket::shutdown
int shutdown()
Definition: UdpSocket.cpp:124
visionary::UdpSocket::m_udpAddr
struct sockaddr_in m_udpAddr
Definition: UdpSocket.h:65
visionary::UdpSocket::initSocket
int initSocket()
Definition: UdpSocket.cpp:34
visionary::UdpSocket::connect
int connect(const std::string &hostname, uint16_t port)
Definition: UdpSocket.cpp:75


sick_safevisionary_base
Author(s):
autogenerated on Sat Oct 21 2023 02:24:26