Last active
November 13, 2021 09:03
-
-
Save zonque/ccd4a670360b158b156d to your computer and use it in GitHub Desktop.
Simple client/server multicast test
This file contains hidden or 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
| /* | |
| * Compile: | |
| * | |
| * gcc mcasttest.c -o server -Wall | |
| * ln -s server client | |
| * | |
| * Invoke: | |
| * | |
| * ./client | |
| * ./server | |
| */ | |
| #include <string.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <unistd.h> | |
| #include <libgen.h> | |
| #include <sys/types.h> | |
| #include <sys/socket.h> | |
| #include <netinet/in.h> | |
| #include <arpa/inet.h> | |
| #define HELLO_PORT 12345 | |
| #define HELLO_GROUP "225.0.0.37" | |
| #define MSGBUFSIZE 256 | |
| static void die(const char *s) { | |
| perror(s); | |
| exit(1); | |
| } | |
| static void server(void) { | |
| char *message = "Hello, World!"; | |
| int fd, r; | |
| struct sockaddr_in addr = { | |
| .sin_family = AF_INET, | |
| .sin_addr.s_addr = inet_addr(HELLO_GROUP), | |
| .sin_port = htons(HELLO_PORT), | |
| }; | |
| /* create what looks like an ordinary UDP socket */ | |
| fd = socket(AF_INET, SOCK_DGRAM, 0); | |
| if (fd < 0) | |
| die("socket"); | |
| for (;;) { | |
| r = sendto(fd, message, strlen(message) + 1, 0, (struct sockaddr *) &addr, sizeof(addr)); | |
| if (r < 0) | |
| die("sendto"); | |
| sleep(1); | |
| } | |
| } | |
| static void client(void) { | |
| int r, fd; | |
| char msgbuf[MSGBUFSIZE]; | |
| unsigned one = 1; | |
| struct sockaddr_in addr = { | |
| .sin_family = AF_INET, | |
| .sin_addr.s_addr = htonl(INADDR_ANY), | |
| .sin_port = htons(HELLO_PORT), | |
| }; | |
| struct ip_mreq mreq = { | |
| .imr_multiaddr.s_addr = inet_addr(HELLO_GROUP), | |
| .imr_interface.s_addr = htonl(INADDR_ANY), | |
| }; | |
| fd = socket(AF_INET, SOCK_DGRAM, 0); | |
| if (fd < 0) | |
| die("socket"); | |
| r = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); | |
| if (r < 0) | |
| die("setsockopt(SO_REUSEADDR)"); | |
| r = bind(fd, (struct sockaddr *) &addr,sizeof(addr)); | |
| if (r < 0) | |
| die("bind"); | |
| r = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); | |
| if (r < 0) | |
| die("setsockopt(IP_ADD_MEMBERSHIP)"); | |
| for (;;) { | |
| unsigned addrlen = sizeof(addr); | |
| int nbytes; | |
| nbytes = recvfrom(fd, msgbuf, MSGBUFSIZE, 0, (struct sockaddr *) &addr, &addrlen); | |
| if (nbytes < 0) | |
| die("recvfrom"); | |
| printf("received %d bytes: >%s<\n", nbytes, msgbuf); | |
| } | |
| } | |
| int main(int argc, char **argv) { | |
| if (strstr(basename(argv[0]), "server")) | |
| server(); | |
| else | |
| client(); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment