As far as coding is concerned, there are two big differences
between UDP and TCP.
- The second argument to the
socket system
call is SOCK_DGRAM instead of
SOCK_STREAM, and
- 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);
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;
}