15.6 Unix Domain Datagram
Client/Server
We now recode our UDP client/server from
Sections 8.3 and
8.5 to use Unix
domain datagram sockets. Figure 15.5 shows the server, which is a
modification of Figure 8.3.
Figure 15.4
Unix domain stream protocol echo client.
unixdomain/unixstrcli01.c
1 #include "unp.h"
2 int
3 main(int argc, char **argv)
4 {
5 int sockfd;
6 struct sockaddr_un servaddr;
7 sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
8 bzero(&servaddr, sizeof(servaddr));
9 servaddr.sun_family = AF_LOCAL;
10 strcpy(servaddr.sun_path, UNIXSTR_PATH);
11 Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
12 str_cli(stdin, sockfd); /* do it all */
13 exit(0);
14 }
Figure 15.5
Unix domain datagram protocol echo server.
unixdomain/unixdgserv01.c
1 #include "unp.h"
2 int
3 main(int argc, char **argv)
4 {
5 int sockfd;
6 struct sockaddr_un servaddr, cliaddr;
7 sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);
8 unlink(UNIXDG_PATH);
9 bzero(&servaddr, sizeof(servaddr));
10 servaddr.sun_family = AF_LOCAL;
11 strcpy(servaddr.sun_path, UNIXDG_PATH);
12 Bind(sockfd, (SA *) &servaddr, sizeof(servaddr));
13 dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
14 }
6 The
datatype of the two socket address structures is now
sockaddr_un.
7 The
first argument to socket is AF_LOCAL, to create a
Unix domain datagram socket.
8鈥?2
The constant UNIXDG_PATH is defined in unp.h to
be /tmp/unix.dg. We first unlink the pathname, in
case it exists from an earlier run of the server, and then
initialize the socket address structure before calling
bind. An error from unlink is acceptable.
13 The
same dg_echo function is used (Figure 8.4).
Figure
15.6 is the Unix domain datagram protocol echo client. It is a
modification of Figure 8.7.
Figure 15.6
Unix domain datagram protocol echo client.
unixdomain/unixdgcli01.c
1 #include "unp.h"
2 int
3 main(int argc, char **argv)
4 {
5 int sockfd;
6 struct sockaddr_un cliaddr, servaddr;
7 sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);
8 bzero(&cliaddr, sizeof(cliaddr)); /* bind an address for us */
9 cliaddr.sun_family = AF_LOCAL;
10 strcpy(cliaddr.sun_path, tmpnam(NULL));
11 Bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
12 bzero(&servaddr, sizeof(servaddr)); /* fill in server's address */
13 servaddr.sun_family = AF_LOCAL;
14 strcpy(servaddr.sun_path, UNIXDG_PATH);
15 dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
16 exit(0);
17 }
6 The
socket address structure to contain the server's address is now a
sockaddr_un structure. We also allocate one of these
structures to contain the client's address, which we will talk
about shortly.
7 The
first argument to socket is AF_LOCAL.
8鈥?1
Unlike our UDP client, when using the Unix domain datagram
protocol, we must explicitly bind a pathname to our socket
so that the server has a pathname to which it can send its reply.
We call tmpnam to assign a unique pathname that we then
bind to our socket. Recall from Section 15.4 that
sending a datagram on an unbound Unix domain datagram socket does
not implicitly bind a pathname to the socket. Therefore, if we omit
this step, the server's call to recvfrom in the
dg_echo function returns a null pathname, which then
causes an error when the server calls sendto.
12鈥?4
The code to fill in the socket address structure with the server's
well-known pathname is identical to the code shown earlier for the
server.
15 The
function dg_cli is the same as that shown in Figure
8.8.
|