simple-socket library 1.2.0
UDPSocket.cpp
Go to the documentation of this file.
1#include "UDPSocket.h"
2#include "TempFailure.h"
3
4#include <sys/socket.h>
5#include <arpa/inet.h>
6#include <poll.h>
7
8using namespace NET;
9
10namespace {
11
12void setBroadcast( int socket)
13{
14 // If this fails, we'll hear about it when we try to send. This will allow
15 // systems that cannot broadcast to continue if they don't plan to broadcast
16 int broadcastPermission = 1;
17 setsockopt( socket,
18 SOL_SOCKET,
19 SO_BROADCAST,
20 (raw_type*)&broadcastPermission,
21 sizeof(broadcastPermission));
22}
23
24int groupAction( int socket, const std::string& multicastGroup, int action)
25{
26 struct ip_mreq multicastRequest;
27 multicastRequest.imr_multiaddr.s_addr = inet_addr( multicastGroup.c_str());
28 multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY);
29
30 return( setsockopt( socket,
31 IPPROTO_IP,
32 action,
33 (raw_type*)&multicastRequest,
34 sizeof(multicastRequest)));
35}
36
37} // namespace
38
40: InternetSocket( DATAGRAM, IPPROTO_UDP)
41{
42 setBroadcast(m_socket);
43}
44
45void UDPSocket::sendTo( const void* buffer, size_t len, std::string_view foreignAddress, unsigned short foreignPort)
46{
47 sockaddr_in destAddr;
48 fillAddress( foreignAddress, foreignPort, destAddr);
49
50 int sent = TEMP_FAILURE_RETRY (::sendto( m_socket, (const raw_type*)buffer, len, 0, (sockaddr*)&destAddr, sizeof(destAddr)));
51
52 // Write out the whole buffer as a single message
53 if( sent != (int)len)
54 throw SocketException("Send failed (sendto)");
55}
56
57int UDPSocket::receiveFrom( void* buffer, size_t len, std::string& sourceAddress, unsigned short& sourcePort)
58{
59 sockaddr_in clientAddr;
60 socklen_t addrLen = sizeof(clientAddr);
61
62 int ret = TEMP_FAILURE_RETRY (::recvfrom( m_socket, (raw_type*)buffer, len, 0, (sockaddr*)&clientAddr, &addrLen));
63 if( ret < 0)
64 throw SocketException("Receive failed (recvfrom)");
65
66 sourceAddress = inet_ntoa( clientAddr.sin_addr);
67 sourcePort = ntohs( clientAddr.sin_port);
68
69 return ret;
70}
71
72int UDPSocket::timedReceiveFrom( void* buffer, size_t len, std::string& sourceAddress, unsigned short& sourcePort, int timeout)
73{
74 struct pollfd poll;
75 poll.fd = m_socket;
76 poll.events = POLLIN | POLLPRI | POLLRDHUP;
77
78 int ret = TEMP_FAILURE_RETRY (::poll( &poll, 1, timeout));
79
80 if( ret == 0) return 0;
81 if( ret < 0) throw SocketException("Receive failed (poll)");
82
83 if( poll.revents & POLLRDHUP)
84 m_peerDisconnected = true;
85
86 if( poll.revents & POLLIN || poll.revents & POLLPRI)
87 return receiveFrom( buffer, len, sourceAddress, sourcePort);
88
89 return 0;
90}
91
92void UDPSocket::setMulticastTTL( unsigned char multicastTTL)
93{
94 if( setsockopt( m_socket,
95 IPPROTO_IP,
96 IP_MULTICAST_TTL,
97 (raw_type*)&multicastTTL,
98 sizeof(multicastTTL)) < 0)
99 throw SocketException("Multicast set TTL failed (setsockopt)");
100}
101
102void UDPSocket::setMulticastInterfaceAddr( const std::string& address)
103{
104 struct in_addr interfaceAddr;
105 inet_aton( address.c_str(), &interfaceAddr);
106
107 if( setsockopt( m_socket,
108 IPPROTO_IP,
109 IP_MULTICAST_IF,
110 (raw_type*)&interfaceAddr,
111 sizeof(interfaceAddr)) < 0)
112 throw SocketException("Multicast set Interface Address failed (setsockopt)");
113}
114
115void UDPSocket::joinGroup( const std::string& multicastGroup)
116{
117 if( groupAction( m_socket, multicastGroup, IP_ADD_MEMBERSHIP) < 0)
118 throw SocketException("Multicast group join failed (setsockopt)");
119}
120
121void UDPSocket::leaveGroup( const std::string& multicastGroup)
122{
123 if( groupAction( m_socket, multicastGroup, IP_DROP_MEMBERSHIP) < 0)
124 throw SocketException("Multicast group leave failed (setsockopt)");
125}
static const int len
#define TEMP_FAILURE_RETRY(expression)
Definition TempFailure.h:8
Definition CANFrame.h:7
InternetSocket(int sockfd)
create socket from a SocketHandle returned by an accept() call
static void fillAddress(std::string_view address, unsigned short port, sockaddr_in &addr)
Signals a problem with the execution of a socket call.
int timedReceiveFrom(void *buffer, size_t len, std::string &sourceAddress, unsigned short &sourcePort, int timeout)
Definition UDPSocket.cpp:72
int receiveFrom(void *buffer, size_t len, std::string &sourceAddress, unsigned short &sourcePort)
Definition UDPSocket.cpp:57
void setMulticastTTL(unsigned char multicastTTL)
Definition UDPSocket.cpp:92
void setMulticastInterfaceAddr(const std::string &address)
void joinGroup(const std::string &multicastGroup)
void sendTo(const void *buffer, size_t len, std::string_view foreignAddress, unsigned short foreignPort)
Definition UDPSocket.cpp:45
void leaveGroup(const std::string &multicastGroup)