Taken from the original at http://www.ecst.csuchico.edu/~beej/guide/net/ ... see end of writeup for Copyright statement.

Datagram Sockets

I really don't have that much to talk about here, so I'll just present a couple of sample programs: talker.c and listener.c.

listener sits on a machine waiting for an incoming packet on port 4950. talker sends a packet to that port, on the specified machine, that contains whatever the user enters on the command line.

Here is the source for listener.c:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>

#define MYPORT 4950    /* the port users will be sending to */

#define MAXBUFLEN 100

main()
{
  int sockfd;
  struct sockaddr_in my_addr;    /* my address information */
  struct sockaddr_in their_addr; /* connector's address information */
  int addr_len, numbytes;
  char buf[MAXBUFLEN];

  if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }

  my_addr.sin_family = AF_INET;         /* host byte order */
  my_addr.sin_port = htons(MYPORT);     /* short, network byte order */
  my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
  bzero(&(my_addr.sin_zero), 8);        /* zero the rest of the struct */

  if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) \
        == -1) {
    perror("bind");
    exit(1);
  }

  addr_len = sizeof(struct sockaddr);
  if ((numbytes=recvfrom(sockfd, buf, MAXBUFLEN, 0, \
      (struct sockaddr *)&their_addr, &addr_len)) == -1) {
    perror("recvfrom");
    exit(1);
  }

  printf("got packet from %s\n", inet_ntoa(their_addr.sin_addr));
  printf("packet is %d bytes long\n", numbytes);
  buf[numbytes] = '\0';
  printf("packet contains \"%s\"\n", buf);

  close(sockfd);
}

Notice that in our call to socket() we're finally using SOCK_DGRAM. Also, note that there's no need to listen() or accept(). This is one of the perks of using unconnected datagram sockets!

Next comes the source for talker.c:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/wait.h>

#define MYPORT 4950    /* the port users will be sending to */

int main(int argc, char *argv[])
{
  int sockfd;
  struct sockaddr_in their_addr; /* connector's address information */
  struct hostent *he;
  int numbytes;

  if (argc != 3) {
  fprintf(stderr, "usage: talker hostname message\n");
    exit(1);
  }

  if ((he=gethostbyname(argv[1])) == NULL) {  /* get the host info */
    herror("gethostbyname");
    exit(1);
  }

  if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }

  their_addr.sin_family = AF_INET;      /* host byte order */
  their_addr.sin_port = htons(MYPORT);  /* short, network byte order */
  their_addr.sin_addr = *((struct in_addr *)he->h_addr);
  bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */

  if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0, \
      (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) {
    perror("sendto");
    exit(1);
  }

  printf("sent %d bytes to %s\n", numbytes, inet_ntoa(their_addr.sin_addr));

  close(sockfd);

  return 0;
}

And that's all there is to it! Run listener on some machine, then run talker on another. Watch them communicate! Fun G-rated excitement for the entire nuclear family!

Except for one more tiny detail that I've mentioned many times in the past: connected datagram sockets. I need to talk about this here, since we're in the datagram section of the document. Let's say that talker calls connect() and specifies the listener's address. From that point on, talker may only sent to and receive from the address specified by connect(). For this reason, you don't have to use sendto() and recvfrom(); you can simply use send() and recv().


Prev | Up | Next


Copyright © 1995, 1996 by Brian "Beej" Hall. This guide may be reprinted in any medium provided that its content is not altered, it is presented in its entirety, and this copyright notice remains intact. Contact beej@ecst.csuchico.edu for more information.