Code:
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#define BUFSIZE 100000
int main(int argc, char **argv) {
int sfd, s, rsz, r;
struct addrinfo hints;
struct addrinfo *result, *rp;
ssize_t nrecv;
char buf[BUFSIZE];
struct sockaddr_storage from;
socklen_t fromlen;
char host[NI_MAXHOST], service[NI_MAXSERV];
if (argc != 2) {
printf("Usage: %s port \n", argv[0]);
exit(EXIT_FAILURE);
}
/* Construction of the local address (for bind) */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_protocol = 0;
s = getaddrinfo(NULL, argv[1], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
/* getaddrinfo () returns a list of address structures.
We try each address until bind (2) succeeds.
If socket (2) (or bind (2)) fails, we close the socket and we
try the following address. */
for (rp = result; rp != NULL; rp = rp->ai_next) {
/* Creation of the socket */
sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sfd == -1)
continue;
/* Association of a port to the socket */
r = bind(sfd, rp->ai_addr, rp->ai_addrlen);
if (r == 0)
break; /* Success */
close(sfd);
}
if (rp == NULL) { /* no valid address */
perror("bind");
exit(EXIT_FAILURE);
}
freeaddrinfo(result); /* no need anymore */
/* allow multiple sockets to use the same port number */
int reuse = 1;
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
{
perror("setsockopt SO_REUSEADDR");
}
/* ask the kernel to join a multicast group which is 224.2.2.2*/
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr("224.2.2.2");
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0)
{
perror("setsockopt IP_ADD_MEMBERSHIP");
}
/* communication loop */
for (;;) {
/* data reception */
fromlen = sizeof(from);
nrecv = recvfrom(sfd, &buf, BUFSIZE, 0, (struct sockaddr *)&from, &fromlen);
if (nrecv == -1) {
perror("Socket read error\n");
exit(EXIT_FAILURE);
}
printf("received %zd bytes\n", nrecv);
/* Recognition of the client machine*/
s = getnameinfo((struct sockaddr *)&from, fromlen,
host, NI_MAXHOST, service, NI_MAXSERV,
NI_NUMERICHOST | NI_NUMERICSERV);
if (s == 0)
printf("Transmitter '%s' Port '%s'\n", host, service);
else
printf("Error: %s\n", gai_strerror(s));
}
}