listener.cpp

Go to the documentation of this file.
00001 /*
00002 ** listener.c -- a datagram sockets "server" demo
00003 *
00004 * From:
00005 * http://beej.us/guide/bgnet/output/html/multipage/clientserver.html#datagram
00006 */
00007 
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <unistd.h>
00011 #include <errno.h>
00012 #include <string.h>
00013 #include <sys/types.h>
00014 #include <sys/socket.h>
00015 #include <netinet/in.h>
00016 #include <arpa/inet.h>
00017 #include <netdb.h>
00018 
00019 #define MYPORT "4950"    // the port users will be connecting to
00020 
00021 #define MAXBUFLEN 100
00022 
00023 // get sockaddr, IPv4 or IPv6:
00024 void *get_in_addr(struct sockaddr *sa)
00025 {
00026     if (sa->sa_family == AF_INET) {
00027         return &(((struct sockaddr_in*)sa)->sin_addr);
00028     }
00029 
00030     return &(((struct sockaddr_in6*)sa)->sin6_addr);
00031 }
00032 
00033 int main(void)
00034 {
00035     int sockfd;
00036     struct addrinfo hints, *servinfo, *p;
00037     int rv;
00038     int numbytes;
00039     struct sockaddr_storage their_addr;
00040     char buf[MAXBUFLEN];
00041     socklen_t addr_len;
00042     char s[INET6_ADDRSTRLEN];
00043 
00044     memset(&hints, 0, sizeof hints);
00045     hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
00046     hints.ai_socktype = SOCK_DGRAM;
00047     hints.ai_flags = AI_PASSIVE; // use my IP
00048 
00049     if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
00050         fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
00051         return 1;
00052     }
00053 
00054     // loop through all the results and bind to the first we can
00055     for(p = servinfo; p != NULL; p = p->ai_next) {
00056         if ((sockfd = socket(p->ai_family, p->ai_socktype,
00057                 p->ai_protocol)) == -1) {
00058             perror("listener: socket");
00059             continue;
00060         }
00061 
00062         if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
00063             close(sockfd);
00064             perror("listener: bind");
00065             continue;
00066         }
00067 
00068         break;
00069     }
00070 
00071     if (p == NULL) {
00072         fprintf(stderr, "listener: failed to bind socket\n");
00073         return 2;
00074     }
00075 
00076     freeaddrinfo(servinfo);
00077 
00078     printf("listener: waiting to recvfrom...\n");
00079 
00080     addr_len = sizeof their_addr;
00081     if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
00082         (struct sockaddr *)&their_addr, &addr_len)) == -1) {
00083         perror("recvfrom");
00084         exit(1);
00085     }
00086 
00087     printf("listener: got packet from %s\n",
00088         inet_ntop(their_addr.ss_family,
00089             get_in_addr((struct sockaddr *)&their_addr),
00090             s, sizeof s));
00091     printf("listener: packet is %d bytes long\n", numbytes);
00092     buf[numbytes] = '\0';
00093     printf("listener: packet contains \"%s\"\n", buf);
00094 
00095     close(sockfd);
00096 
00097     return 0;
00098 }