Skip to content

Instantly share code, notes, and snippets.

@jimdigriz
Last active April 12, 2025 05:08
Show Gist options
  • Select an option

  • Save jimdigriz/2324a6c93e764541b4432c0d2f127c9a to your computer and use it in GitHub Desktop.

Select an option

Save jimdigriz/2324a6c93e764541b4432c0d2f127c9a to your computer and use it in GitHub Desktop.
Simple Multicast Sender and Receiver in C over the Loopback interface
/* receiver run: gcc -o r r.c && ./r */
#include <arpa/inet.h>
#include <assert.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
/* change to tune into another channel */
#define PORT 10000
int main(int argc, char *argv[]) {
int fd = socket(AF_INET, SOCK_DGRAM, 0);
assert(fd >= 0);
struct ifreq ifr = { .ifr_name = "lo" };
assert(setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == 0);
char yes = '\1';
assert(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == 0);
struct sockaddr_in src = {0};
src.sin_family = AF_INET;
src.sin_addr.s_addr = htonl(INADDR_ANY);
src.sin_port = htons(PORT);
assert(bind(fd, (struct sockaddr *)&src, sizeof(src)) == 0);
struct ip_mreq mreq = {0};
mreq.imr_multiaddr.s_addr = inet_addr("239.0.0.1");
mreq.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
assert(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == 0);
ssize_t len;
char buf[100];
while (1) {
len = recv(fd, &buf, sizeof(buf), 0);
printf("%.*s\n", len, buf);
}
return 0;
}
/* sender run: gcc -o s s.c && ./s */
#include <arpa/inet.h>
#include <assert.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
char payload[] = "hello world ";
int fd = socket(AF_INET, SOCK_DGRAM, 0);
assert(fd >= 0);
struct ifreq ifr = { .ifr_name = "lo" };
assert(setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == 0);
struct sockaddr_in src = {0};
src.sin_family = AF_INET;
src.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
assert(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &src, sizeof(src)) == 0);
char loop = '\1';
assert(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, 1) == 0);
struct sockaddr_in dst = {0};
dst.sin_family = AF_INET;
dst.sin_addr.s_addr = inet_addr("239.0.0.1");
while (1) {
for (int i = 10000; i < 10100; i++) {
sprintf(&payload[12], "%d", i);
dst.sin_port = htons(i);
sendto(fd, &payload, sizeof(payload) - 1, 0, (struct sockaddr *)&dst, sizeof(dst));
}
sleep(1);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment