Unix Network Programming Manual
Datagram Example
The following programs are an example of a datagram style network programming
application. They are written for client/server model, with the server
providing a data translation service. Note that the client cannot receive
messages except from processes to which it has sent a message, because it
has not created a socket and bound an address.
/* ===============================================> dg_server.c
* Simple datagram server for Internet domain sockets. It opens
* a socket and then performs a simple transposition on
* incoming messages before sending them back.
*
* The only argument is the port to utilize.
* ================================================================
*/
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int main
(
int argc,
char *argv []
)
{
int sock, addrsize, nbyte, ct;
struct sockaddr_in addr;
struct servent *serv;
char buf[80], tc;
/*
* Create a socket for datagram communications.
*/
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
{ perror("opening socket");
exit(-1);
}
/*
* Extract the port and bind it to the socket.
*/
addr . sin_family = AF_INET;
serv = getservbyname (argv [1], "udp");
addr . sin_port = serv -> s_port;
addrsize = sizeof (addr);
addr . sin_addr . s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *) &addr, addrsize) == -1)
{ perror("on bind");
exit(-1);
}
/*
* Wait for a message to come in through the socket. The
* address of the sender is contained in the addr structure
* so that a return can be sent. Note that this is an infinite loop
*
* For datagrams, there is no listen or accept call, because there is
* no connection. The server waits for a message, transposes it and
* sends a response.
*/
do
{
addrsize = sizeof (struct sockaddr_in);
nbyte = recvfrom(sock, buf, 80, 0, (struct sockaddr *) &addr,
&addrsize);
if (nbyte > 0)
printf("server: %s \n", buf,
inet_ntoa (addr . sin_addr));
else
break;
/*
* Encode the string by exchanging odd and even pairs.
*/
for (ct = 0; ct < nbyte-1; ct += 2)
{
tc = buf[ct];
buf[ct] = buf[ct+1];
buf[ct+1] = tc;
}
/*
* Send the message back to the originator.
*/
nbyte = sendto (sock, buf, nbyte, 0, (struct sockaddr *) &addr,
addrsize);
} while (1);
/*
* It should never get here, but close the socket
*/
printf ("Datagram server terminating\n");
shutdown(sock, 2); /* not receiving or sending anymore */
close(sock);
return( 0 );
}
/* ==================================================> dg_client.c
* Simple Unix domain datagram type peer process. It comes up and
* sends messages to another process.
* ==============================================================
*/
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int main
(
int argc,
char *argv []
)
{
int flag, sock, addrsize, saddrsize, response;
struct sockaddr_in addr, saddr;
struct hostent *host;
struct servent *serv;
int getmsg(), done, len, rlen;
char socketname[20], buf[80];
/*
* Create a socket.
*/
sock = socket(AF_INET, SOCK_DGRAM,0);
if (sock == -1)
{ perror("opening socket");
exit(-1);
}
/*
* Get the correct port and host address from the args and build the
* address of the server. There's no bind in the client, because it
* is sending to the server's address.
*/
serv = getservbyname (argv [1], "udp");
addr . sin_port = serv -> s_port;
addr . sin_family = AF_INET;
host = gethostbyname (argv [2]);
addr . sin_addr . s_addr = *((in_addr_t *) host -> h_addr_list [0]);
addrsize = sizeof (struct sockaddr_in);
/*
* Get messages from the user and then send them to the server to be
* processed and returned.
*
* Note that the null message is sent to kill the server.
*/
done = 0;
do
{
printf ("Enter a short message to be sent, return to halt\n");
gets (buf);
len = strlen (buf);
if (len < 2) /* Crude, but effective for a short example */
done = 1;
if(sendto(sock, buf, len, 0, (struct sockaddr *) &addr, addrsize) < 0)
perror("on client write");
saddrsize = sizeof (struct sockaddr_in);
rlen = recvfrom (sock, buf, len, 0, (struct sockaddr *) &saddr,
&saddrsize);
printf ("client: %s returned from %s\n", buf,
inet_ntoa (addr . sin_addr));
} while (! done);
/*
* Close the socket and unlink the socket name
* which means delete the file representing the socket
*/
shutdown(sock, 2); /* not receiving or sending anymore */
close(sock);
return( 0 );
}