Last active
June 23, 2022 09:20
-
-
Save dksmiffs/d67afe6bda973d67752ae63dc49a7310 to your computer and use it in GitHub Desktop.
Linux C++ UDP multicast example, guidance here: https://www.tenouk.com/Module41c.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Guidance: https://www.tenouk.com/Module41c.html | |
#include <arpa/inet.h> | |
#include <array> | |
#include <iostream> | |
#include <netinet/in.h> | |
#include "udpSock.hpp" | |
#include "zz_diagnose.hpp" | |
int main() | |
{ | |
UdpSock sock; | |
diagnose(sock.isGood(), "Opening datagram socket for receive"); | |
{ | |
// enable SO_REUSEADDR to allow multiple instances of this application to | |
// receive copies of the multicast datagrams. | |
int reuse = 1; | |
diagnose(setsockopt(sock(), SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, | |
sizeof(reuse)) >= 0, "Setting SO_REUSEADDR"); | |
} | |
// Bind to the proper port number with the IP address specified as INADDR_ANY | |
sockaddr_in localSock = {}; // initialize to all zeroes | |
localSock.sin_family = AF_INET; | |
localSock.sin_port = htons(4321); | |
localSock.sin_addr.s_addr = INADDR_ANY; | |
// Note from manpage that bind returns 0 on success | |
diagnose(!bind(sock(), (sockaddr*)&localSock, sizeof(localSock)), | |
"Binding datagram socket"); | |
// Join the multicast group on the local interface. Note that this | |
// IP_ADD_MEMBERSHIP option must be called for each local interface over | |
// which the multicast datagrams are to be received. | |
ip_mreq group = {}; // initialize to all zeroes | |
group.imr_multiaddr.s_addr = inet_addr("226.1.1.1"); | |
group.imr_interface.s_addr = inet_addr("127.0.0.1"); | |
diagnose(setsockopt(sock(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&group, | |
sizeof(group)) >= 0, "Adding multicast group"); | |
// Read from the socket | |
std::array<char, 1024> arr; | |
arr.fill(0); | |
diagnose(read(sock(), arr.data(), arr.size()) >= 0, | |
"Reading datagram message"); | |
std::cout << "Message from multicast sender: " << arr.data() | |
<< std::endl; | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Guidance: www.tenouk.com/Module41c.html | |
#include <arpa/inet.h> | |
#include <netinet/in.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include "udpSock.hpp" | |
#include "zz_diagnose.hpp" | |
int main() | |
{ | |
UdpSock sock; | |
diagnose(sock.isGood(), "Opening datagram socket for send"); | |
sockaddr_in groupSock = {}; // init to all zeroes | |
groupSock.sin_family = AF_INET; | |
groupSock.sin_addr.s_addr = inet_addr("226.1.1.1"); | |
groupSock.sin_port = htons(4321); | |
in_addr localIface = {}; // init to all zeroes | |
localIface.s_addr = inet_addr("127.0.0.1"); | |
diagnose(setsockopt(sock(), IPPROTO_IP, IP_MULTICAST_IF, (char*)&localIface, | |
sizeof(localIface)) >= 0, "Setting local interface"); | |
const std::string databuf = "Multicast from C++"; | |
diagnose(sendto(sock(), databuf.c_str(), databuf.length(), 0, | |
(sockaddr*)&groupSock, sizeof(groupSock)) >= 0, | |
"Sending datagram message"); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/socket.h> | |
#include <unistd.h> | |
class UdpSock { | |
public: | |
UdpSock() { | |
m_sd = socket(AF_INET, SOCK_DGRAM, 0); | |
} | |
~UdpSock() { | |
// make sure the socket resource doesn't leak | |
if (isGood()) | |
close(m_sd); | |
} | |
// Don't need the other default operations | |
UdpSock(const UdpSock&) = delete; | |
UdpSock& operator=(const UdpSock&) = delete; | |
UdpSock(UdpSock&&) = delete; | |
UdpSock& operator=(UdpSock&&) = delete; | |
int operator()() const { | |
return m_sd; | |
} | |
bool isGood() const { | |
return m_sd >= 0; | |
} | |
private: | |
int m_sd = -1; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// unusual file name is a hack to force GitHub Gist not to put this file at the top | |
#include <iostream> | |
#include <stdlib.h> | |
#include <string> | |
void diagnose(bool isGood, const std::string& action) | |
{ | |
if (isGood) | |
std::cout << action.c_str() << " OK" << std::endl; | |
else | |
{ | |
std::cerr << action.c_str() << " error" << std::endl; | |
exit(1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment