
A datagram socket provides a symmetric data exchange interface without requiring connection establishment. Each message carries the destination address. The following figure shows the flow of communication between server and client.
The bind(3SOCKET) step for the server is optional.
Figure 8.
sendto(s, buf, buflen, flags, (struct sockaddr *) &to, tolen);
The s, buf, buflen, and flags parameters are the same as in connection-oriented sockets. The to and tolen values indicate the address of the intended recipient of the message. A locally detected error condition, such as an unreachable network, causes a return of -1 and errno to be set to the error number. 8-5 Sending an Internet Family Datagram
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #define DATA "The sea is calm, the tide is full . . ." /* * Here I send a datagram to a receiver whose name I get from * the command line arguments. The form of the command line is: * dgramsend hostname portnumber */ main(int argc, char *argv[]) { int sock, errnum; struct sockaddr_in6 name; struct hostent *hp; /* Create socket on which to send. */ sock = socket(AF_INET6,SOCK_DGRAM, 0); if (sock == -1) { perror("opening datagram socket"); exit(1); } /* * Construct name, with no wildcards, of the socket to ``send'' * to. getinodebyname returns a structure including the network * address of the specified host. The port number is taken from * the command line. */ hp = getipnodebyname(argv[1], AF_INET6, AI_DEFAULT, &errnum); if (hp == (struct hostent *) 0) { fprintf(stderr, "%s: unknown host\n", argv[1]); exit(2); } bzero (&name, sizeof (name)); memcpy((char *) &name.sin6_addr, (char *) hp->h_addr, hp->h_length); name.sin6_family = AF_INET6; name.sin6_port = htons(atoi(argv[2])); /* Send message. */ if (sendto(sock,DATA, sizeof DATA ,0, (struct sockaddr *) &name,sizeof name) == -1) perror("sending datagram message"); close(sock); exit(0); }
The following sample code shows how to read an Internet call by creating a socket, binding a name to the socket, and then reading from the socket.
Example 8-6 Reading Internet Family Datagrams
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> /* * This program creates a datagram socket, binds a name to it, then * reads from the socket. */ main() { int sock, length; struct sockaddr_in6 name; char buf[1024]; /* Create socket from which to read. */ sock = socket(AF_INET6, SOCK_DGRAM, 0); if (sock == -1) { perror("opening datagram socket"); exit(1); } /* Create name with wildcards. */ bzero (&name, sizeof (name)); name.sin6_family = AF_INET6; name.sin6_addr = in6addr_any; name.sin6_port = 0; if (bind (sock, (struct sockaddr *)&name, sizeof (name)) == -1) { perror("binding datagram socket"); exit(1); } /* Find assigned port value and print it out. */ length = sizeof(name); if (getsockname(sock,(struct sockaddr *) &name, &length) == -1) { perror("getting socket name"); exit(1); } printf("Socket port #%d\n", ntohs(name.sin6_port)); /* Read from the socket. */ if (read(sock, buf, 1024) == -1 ) perror("receiving datagram packet"); /* Assumes the data is printable */ printf("-->%s\n", buf); close(sock); exit(0); }