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