Menu

Class 22: Networks V, a UDP Client


Reading
APUE 16.5, especially the connection-less client and server examples.

Homework
None.

UDP vs. TCP
Recall that UDP is a protocol for communication via datagrams rather than byte-streams. It is connectionless and unreliable, but ... there's less overhead involved. For some applications, UDP is a better approach. This class is about UDP client programs.

The big difference in code
As far as coding is concerned, there are two big differences between UDP and TCP.
  1. The second argument to the socket system call is SOCK_DGRAM instead of SOCK_STREAM, and
  2. data is not sent/recieved with the familiar read/write system calls (or fscanf/fprintf C IO calls).
Obviously, point 1 is trivial. What about point 2? Fundamentally, read/write/fscanf/fprintf all assume a file descriptor that provides a stream-of-characters ... precisely what we don't have for UDP. With UDP, each datagram needs to be sent with a destination address, so whatever function allows us to send data is going to need extra parameters for passing the host+port. When we receive a datagram, we really don't know in advance where it's coming from, so whatever function we use for recieving will need extra parameters to provide us with the host+port from whence the datagram came. The two system calls we'll discuss for sending/recieving datagrams are:
ssize_t sendto(int s,  const  void  *msg,  size_t  len,  int flags, const struct sockaddr *to, int  tolen);

ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);

A simple client
In class I provided you with a running server on a particular host and port. Your job was to write a client that would read in a server name and a message and send it to the server, which would then print out the message. Here's more or less what you should've gotten:
/***********************************************************
 * A simple client that sends datagrams to a server.  It 
 * assumes port 10000.
 ***********************************************************/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int main(int argc, char **argv)
{
  // Set up socket
  int sfd = socket(AF_INET,SOCK_DGRAM,0);
  if (sfd == -1) { fprintf(stderr,"Socket not created!\n"); exit(2); }

  // Read server name
  char name[256];
  scanf("%s",name);
  
  // get host ip address
  struct hostent *p;
  p = gethostbyname(name);
  if (p == NULL) { fprintf(stderr,"Name '%s' not found!\n",name); continue; }
  unsigned int *ip = (unsigned int*)(p->h_addr_list[0]);
  
  // Set up address structure
  struct sockaddr_in targetsa;
  targetsa.sin_family = AF_INET;
  targetsa.sin_addr.s_addr = *ip;
  targetsa.sin_port = htons(10000);
  
  // Read message and send to server
  char msg[257] = {'\0'};
  fgets(msg,256,stdin);
  int s = sendto(sfd,msg,strlen(msg),0,(struct sockaddr*)&targetsa,sizeof(targetsa));
  if (s == -1) { fprintf(stderr,"Sendto failed!\n"); continue; }
  
  
  shutdown(sfd,SHUT_RDWR);

  return 0;
}