©2004 by Marc J. Rochkind. All rights reserved. Portions marked "Open Source" may be copied under license.

 

Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

c8/sktexm.c

Go to the documentation of this file.
00001 /*
00002     Socket example program (multiple clients)
00003     AUP2, Sec. 8.01.3
00004 
00005     Copyright 2003 by Marc J. Rochkind. All rights reserved.
00006     May be copied only for purposes and under conditions described
00007     on the Web page www.basepath.com/aup/copyright.htm.
00008 
00009     The Example Files are provided "as is," without any warranty;
00010     without even the implied warranty of merchantability or fitness
00011     for a particular purpose. The author and his publisher are not
00012     responsible for any damages, direct or incidental, resulting
00013     from the use or non-use of these Example Files.
00014 
00015     The Example Files may contain defects, and some contain deliberate
00016     coding mistakes that were included for educational reasons.
00017     You are responsible for determining if and how the Example Files
00018     are to be used.
00019 
00020 */
00021 #include "defs.h"
00022 #include <sys/socket.h>
00023 #include <sys/un.h>
00024 /*[run_server]*/
00025 static bool run_server(struct sockaddr_un *sap)
00026 {
00027     int fd_skt, fd_client, fd_hwm = 0, fd;
00028     char buf[100];
00029     fd_set set, read_set;
00030     ssize_t nread;
00031 
00032     ec_neg1( fd_skt = socket(AF_UNIX, SOCK_STREAM, 0) )
00033     ec_neg1( bind(fd_skt, (struct sockaddr *)sap, sizeof(*sap)) )
00034     ec_neg1( listen(fd_skt, SOMAXCONN) )
00035     if (fd_skt > fd_hwm)
00036         fd_hwm = fd_skt;
00037     FD_ZERO(&set);
00038     FD_SET(fd_skt, &set);
00039     while (true) {
00040         read_set = set;
00041         ec_neg1( select(fd_hwm + 1, &read_set, NULL, NULL, NULL) )
00042         for (fd = 0; fd <= fd_hwm; fd++)
00043             if (FD_ISSET(fd, &read_set)) {
00044                 if (fd == fd_skt) {
00045                     ec_neg1( fd_client = accept(fd_skt, NULL, 0) )
00046                     FD_SET(fd_client, &set);
00047                     if (fd_client > fd_hwm)
00048                         fd_hwm = fd_client;
00049                 }
00050                 else {
00051                     ec_neg1( nread = read(fd, buf, sizeof(buf)) )
00052                     if (nread == 0) {
00053                         FD_CLR(fd, &set);
00054                         if (fd == fd_hwm)
00055                             fd_hwm--;
00056                         ec_neg1( close(fd) )
00057                     }
00058                     else {
00059                         printf("Server got \"%s\"\n", buf);
00060                         ec_neg1( write(fd, "Goodbye!", 9 ) )
00061                     }
00062                 }
00063             }
00064     }
00065     ec_neg1( close(fd_skt) )
00066     return true;
00067 
00068 EC_CLEANUP_BGN
00069     return false;
00070 EC_CLEANUP_END
00071 }
00072 /*[run_clients]*/
00073 static bool run_client(struct sockaddr_un *sap)
00074 {
00075     if (fork() == 0) {
00076         int fd_skt;
00077         char buf[100];
00078 
00079         ec_neg1( fd_skt = socket(AF_UNIX, SOCK_STREAM, 0) )
00080         while (connect(fd_skt, (struct sockaddr *)sap, sizeof(*sap)) == -1)
00081             if (errno == ENOENT) {
00082                 sleep(1);
00083                 continue;
00084             }
00085             else
00086                 EC_FAIL
00087         snprintf(buf, sizeof(buf), "Hello from %ld!",
00088           (long)getpid());
00089         ec_neg1( write(fd_skt, buf, strlen(buf) + 1 ) )
00090         ec_neg1( read(fd_skt, buf, sizeof(buf)) )
00091         printf("Client got \"%s\"\n", buf);
00092         ec_neg1( close(fd_skt) )
00093         exit(EXIT_SUCCESS);
00094     }
00095     return true;
00096 
00097 EC_CLEANUP_BGN
00098     /* only child gets here */
00099     exit(EXIT_FAILURE);
00100 EC_CLEANUP_END
00101 }
00102 /*[main]*/
00103 #define SOCKETNAME "MySocket"
00104 
00105 int main(void)
00106 {
00107     struct sockaddr_un sa;
00108     int nclient;
00109 
00110     (void)unlink(SOCKETNAME);
00111     strcpy(sa.sun_path, SOCKETNAME);
00112     sa.sun_family = AF_UNIX;
00113     for (nclient = 1; nclient <= 4; nclient++)
00114         ec_false( run_client(&sa) )
00115     ec_false( run_server(&sa) )
00116     exit(EXIT_SUCCESS);
00117 
00118 EC_CLEANUP_BGN
00119         exit(EXIT_FAILURE);
00120 EC_CLEANUP_END
00121 }
00122 /*[]*/

Generated on Fri Apr 23 10:57:02 2004 for AUP2 Example Source by doxygen 1.3.1