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.