15.5 Unix Domain Stream
Client/Server
We now recode our TCP echo client/server from
Chapter 5
to use Unix domain sockets. Figure 15.3 shows the server, which is a
modification of Figure 5.12 to use
the Unix domain stream protocol instead of TCP.
8 The
datatype of the two socket address structures is now
sockaddr_un.
10 The
first argument to socket is AF_LOCAL, to create a
Unix domain stream socket.
11鈥?5
The constant UNIXSTR_PATH is defined in unp.h to
be /tmp/unix.str. 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.
Notice that this call to bind differs
from the call in Figure 15.2. Here, we
specify the size of the socket address structure (the third
argument) as the total size of the sockaddr_un structure,
not just the number of bytes occupied by the pathname. Both lengths
are valid since the pathname must be null-terminated.
The remainder of the function is the same as
Figure 5.12. The same
str_echo function is used (Figure 5.3).
Figure 15.4 is the
Unix domain stream protocol echo client. It is a modification of
Figure 5.4.
6 The
socket address structure to contain the server's address is now a
sockaddr_un structure.
7 The
first argument to socket is AF_LOCAL.
8鈥?0
The code to fill in the socket address structure is identical to
the code shown for the server: Initialize the structure to 0, set
the family to AF_LOCAL, and copy the pathname into the
sun_path member.
12 The
function str_cli is the same as earlier (Figure
6.13 was the last version we developed).
Figure 15.3
Unix domain stream protocol echo server.
unixdomain/unixstrserv01.c
1 #include "unp.h"
2 int
3 main(int argc, char **argv)
4 {
5 int listenfd, connfd;
6 pid_t childpid;
7 socklen_t clilen;
8 struct sockaddr_un cliaddr, servaddr;
9 void sig_chld(int);
10 listenfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
11 unlink(UNIXSTR_PATH);
12 bzero(&servaddr, sizeof(servaddr));
13 servaddr.sun_family = AF_LOCAL;
14 strcpy(servaddr.sun_path, UNIXSTR_PATH);
15 Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
16 Listen(listenfd, LISTENQ);
17 Signal(SIGCHLD, sig_chld);
18 for ( ; ; ) {
19 clilen = sizeof(cliaddr);
20 if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
21 if (errno == EINTR)
22 continue; /* back to for() */
23 else
24 err_sys("accept error");
25 }
26 if ( (childpid = Fork()) == 0) { /* child process */
27 Close(listenfd); /* close listening socket */
28 str_echo(connfd); /* process request */
29 exit(0);
30 }
31 Close(connfd); /* parent closes connected socket */
32 }
33 }
|