UNIX Network Programming Volume 1, Third Edition [Electronic resources] : The Sockets Networking API نسخه متنی

This is a Digital Library

With over 100,000 free electronic resource in Persian, Arabic and English

UNIX Network Programming Volume 1, Third Edition [Electronic resources] : The Sockets Networking API - نسخه متنی

Addison Wesley

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید










11.16 udp_server Function


Our final UDP function that provides a simpler interface to getaddrinfo is udp_server.

#include "unp.h"

int udp_server (const char *

hostname , const char *

service , socklen_t *

lenptr );

Returns: unconnected socket descriptor if OK, no return on error

The arguments are the same as for tcp_listen: an optional

hostname , a required

service (so its port number can be bound), and an optional pointer to a variable in which the size of the socket address structure is returned.

Figure 11.18 shows the source code.

Figure 11.18 udp_server function: creates an unconnected socket for a UDP server.

lib/udp_server.c


1 #include "unp.h"
2 int
3 udp_server(const char *host, const char *serv, socklen_t *addrlenp)
4 {
5 int sockfd, n;
6 struct addrinfo hints, *res, *ressave;
7 bzero(&hints, sizeof(struct addrinfo));
8 hints.ai_flags = AI_PASSIVE;
9 hints.ai_family = AF_UNSPEC;
10 hints.ai_socktype = SOCK_DGRAM;
11 if ( (n = getaddrinfo (host, serv, &hints, &res)) != 0)
12 err_quit ("udp_server error for %s, %s: %s",
13 host, serv, gai_strerror(n));
14 ressave = res;
15 do {
16 sockfd = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
17 if (sockfd < 0)
18 continue; /* error - try next one */
19 if (bind (sockfd, res->ai_addr, res->ai_addrlen) == 0)
20 break; /* success */
21 Close (sockfd); /* bind error - close and try next one */
22 } while ( (res = res->ai_next) != NULL);
23 if (res == NULL) /* errno from final socket() or bind() */
24 err_sys ("udp_server error for %s, %s", host, serv);
25 if (addrlenp)
26 *addrlenp = res->ai_addrlen * return size of protocol address */
27 freeaddrinfo (ressave) ;
28 return (sockfd);
29 }

This function is nearly identical to tcp_listen, but without the call to listen. We set the address family to AF_UNSPEC, but the caller can use the same technique that we described with Figure 11.14 to force a particular protocol (IPv4 or IPv6).

We do not set the SO_REUSEADDR socket option for the UDP socket because this socket option can allow multiple sockets to bind the same UDP port on hosts that support multicasting, as we described in Section 7.5. Since there is nothing like TCP's TIME_WAIT state for a UDP socket, there is no need to set this socket option when the server is started.


Example: Protocol-Independent Daytime Server


Figure 11.14 to use UDP.

Figure 11.19 Protocol-independent UDP daytime server.

names/daytimeudpsrv2.c


1 #include "unp.h"
2 #include <time.h>
3 int
4 main (int argc, char **argv)
5 {
6 int sockfd;
7 ssize_t n;
8 char buff[MAXLINE];
9 time_t ticks;
10 socklen_t len;
11 struct sockaddr_storage cliaddr;
12 if (argc == 2)
13 sockfd = Udp_server (NULL, argv [1] NULL);
14 else if (argc == 3)
15 sockfd = Udp_server (argv [1], argv [2], NULL);
16 else
17 err_quit ("usage: daytimeudpsrv [ <host> ] <service or port>");
18 for ( ; ; ) {
19 len = sizeof (cliaddr) ;
20 n = Recvfrom (sockfd, buff, MAXLINE, 0, (SA *) &cliaddr, &len);
21 printf ("datagram from %s\n", Sock_ntop ((SA *) &cliaddr, len));
22 ticks = time (NULL) ;
23 snprintf (buff, sizeof (buff), "%.24s\r\n", ctime (&ticks) ) ;
24 Sendto (sockfd, buff, strlen (buff), 0, (SA *) &cliaddr, len) ;
25 }
26 }


/ 450