Most servers operate on a connection-oriented basis, but some services are based on using datagram sockets and are thus connectionless.
The following socket interface functions are used by the server in the example programs:
socket(): create socket
bind(): assign a socket a name
recvfrom(): read a message from a socket
soc_close(): close socket
The program is shown in two variants:
In the first variant (examples 1 and 3), the program is terminated when a message arrives (read()).
In the second variant (examples 2 and 4), the program waits in an endless loop for further messages after a message has been read.
Example 1: Connectionless server without a program loop for AF_INET
#include <stdio.h>
#include <sys.types.h>
#include <sys.socket.h>
#include <ioctl.h>
#include <signal.h>
#include <netinet.in.h>
#include <netdb.h>
#define TESTPORT 2222
/*
* This program creates a datagram socket, assigns it a defined
* port and then reads data from the socket.
*/
main()
{
int sock;
int length;
struct sockaddr_in server;
char buf[1024];
/* Create the socket to be read from. */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0 )
{ perror("Socket datagram");
exit(1);
}
/* Assign the server "server" a name, using wildcards
*/
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(TESTPORT);
if (bind(sock, &server, sizeof server ) < 0)
{ perror("Bind datagram socket");
exit(1);
}
/* Start reading from the server */
length = sizeof(server);
memset(buf,0,sizeof(buf));
if ( recvfrom(sock, buf, 1024,0, &server, &length) < 0 )
{ perror("recvfrom");
exit(1);
}
else
printf("->%s\n",buf);
soc_close(sock);
}
Example 2: Connectionless server with a program loop for AF_INET
#include <sys.types.h>
#include <sys.socket.h>
#include <ioctl.h>
#include <signal.h>
#include <netinet.in.h>
#include <netdb.h>
#include <stdio.h>
#define TESTPORT 2222
/* This program creates a datagram socket, assigns it a defined
* port and then reads data from the socket. */
main()
{
int sock;
int length;
struct sockaddr_in server;
char buf[1024];
/* Create the socket to be read from. */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0 )
{ perror("Socket datagram");
exit(1);
}
/* Assign the server "server" a name using wildcards */
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(TESTPORT);
if (bind(sock, &server, sizeof server ) < 0)
{ perror("Bind datagram socket");
exit(1);
}
/* Start reading from the server */
length = sizeof(server);
for (;;)
{
memset(buf,0,sizeof(buf));
if ( recvfrom(sock, buf, sizeof(buf),0, &server, &length) < 0 )
{ perror("recvfrom");
exit(1);
}
else
printf("->%s\n",buf);
}
/* Since this program runs in an endless loop, the socket
* "sock" is never explicitly closed. However, all sockets
* are closed automatically if the process is aborted.
*/
}
Example 3: Connectionless server without a program loop for AF_INET6
#include <stdio.h>
#include <sys.types.h>
#include <sys.socket.h>
#include <ioctl.h>
#include <signal.h>
#include <netinet.in.h>
#include <netdb.h>
#define TESTPORT 2222
/*
* This program creates a datagram socket, assigns it a defined
* port and then reads data from the socket.
*/
main()
{
int sock;
int length;
struct sockaddr_in6 server;
struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
char buf[1024];
/* Create the socket to be read from. */
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0 )
{ perror("Socket datagram");
exit(1);
}
/* Assign the server "server" a name using wildcards */
server.sin6_family = AF_INET6;
memcpy(server.sin6_addr.s6_addr, in6addr_any.s6_addr, 16) ;
server.sin6_port = htons(TESTPORT);
if (bind(sock, &server, sizeof server ) < 0)
{ perror("Bind datagram socket");
exit(1);
}
/* Start reading from the server */
length = sizeof(server);
memset(buf,0,sizeof(buf));
if ( recvfrom(sock, buf, 1024,0, &server, &length) < 0 )
{ perror("recvfrom");
exit(1);
}
else
printf("->%s\n",buf);
soc_close(sock);
}
Example 4: Connectionless server with a program loop for AF_INET6
#include <sys.types.h>
#include <sys.socket.h>
#include <ioctl.h>
#include <signal.h>
#include <netinet.in.h>
#include <netdb.h>
#include <stdio.h>
#define TESTPORT 2222
/* This program creates a datagram socket, assigns it a defined
* port and then reads data from the socket. */
main()
{
int sock;
int length;
struct sockaddr_in6 server;
struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
char buf[1024];
/* Create the socket to be read from. */
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0 )
{
perror("Socket datagram");
exit(1);
}
/* Assign the server "server" a name using wildcards */
server.sin6_family = AF_INET6;
memcpy(server.sin6_addr.s6_addr ,in6addr_any.s6_addr,16);
server.sin6_port = htons(TESTPORT);
if (bind(sock, &server, sizeof server ) < 0)
perror("Bind datagram socket");
exit(1);
}
/* Start reading from the server */
length = sizeof(server);
for (;;)
{
memset(buf,0,sizeof(buf));
if ( recvfrom(sock, buf, sizeof(buf),0, &server, &length) < 0 )
{
perror("recvfrom");
exit(1);
else
printf("->%s\n",buf);
}
/* Since this program runs in an endless loop, the socket
* "sock" is never explicitly closed. However, all sockets
* are closed automatically if the process is aborted.
*/
}
The following steps are executed in the program examples for AF_INET and AF_INET6:
- The server creates a communications endpoint (socket) and corresponding descriptor with the socket() function.
The server socket is assigned a defined port number with the bind() function so that it can be addressed from the network via this port number.
The recvfrom() function can be used to read from a socket of type SOCK_DGRAM.
The length of the read message is returned as the result. If no message is available, the process is blocked until a message arrives.