[ Team LiB ] |
15.5 Unix Domain Stream Client/ServerWe 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–15 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–10 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 } |
[ Team LiB ] |