00001 /* 00002 SOCK_DGRAM example program (multiple clients) 00003 AUP2, Sec. 8.06.2 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 #ifdef SOLARIS 00023 #define __EXTENSIONS__ 00024 #endif 00025 #include <sys/socket.h> 00026 #undef __EXTENSIONS__ 00027 #include <sys/un.h> 00028 /*[pgm]*/ 00029 #define SOCKETNAME_SERVER "SktOne" 00030 #define SOCKETNAME_CLIENT "SktTwo" 00031 00032 static struct sockaddr_un sa_server; 00033 00034 #define MSG_SIZE 100 00035 00036 static void run_client(int nclient) 00037 { 00038 struct sockaddr_un sa_client; 00039 int fd_skt; 00040 ssize_t nrecv; 00041 char msg[MSG_SIZE]; 00042 int i; 00043 00044 if (fork() == 0) { /* client */ 00045 sleep(1); /* let server startup first */ 00046 ec_neg1( fd_skt = socket(AF_UNIX, SOCK_DGRAM, 0) ) 00047 snprintf(sa_client.sun_path, sizeof(sa_client.sun_path), 00048 "%s-%d", SOCKETNAME_CLIENT, nclient); 00049 (void)unlink(sa_client.sun_path); 00050 sa_client.sun_family = AF_UNIX; 00051 ec_neg1( bind(fd_skt, (struct sockaddr *)&sa_client, 00052 sizeof(sa_client)) ) 00053 for (i = 1; i <= 4; i++) { 00054 snprintf(msg, sizeof(msg), "Message #%d", i); 00055 ec_neg1( sendto(fd_skt, msg, sizeof(msg), 0, 00056 (struct sockaddr *)&sa_server, sizeof(sa_server)) ) 00057 ec_neg1( nrecv = read(fd_skt, msg, sizeof(msg)) ) 00058 if (nrecv != sizeof(msg)) { 00059 printf("client got short message\n"); 00060 break; 00061 } 00062 printf("Got \"%s\" back\n", msg); 00063 } 00064 ec_neg1( close(fd_skt) ) 00065 exit(EXIT_SUCCESS); 00066 } 00067 return; 00068 00069 EC_CLEANUP_BGN 00070 exit(EXIT_FAILURE); 00071 EC_CLEANUP_END 00072 } 00073 00074 static void run_server(void) 00075 { 00076 int fd_skt; 00077 ssize_t nrecv; 00078 char msg[MSG_SIZE]; 00079 struct sockaddr_storage sa; 00080 socklen_t sa_len; 00081 00082 ec_neg1( fd_skt = socket(AF_UNIX, SOCK_DGRAM, 0) ) 00083 ec_neg1( bind(fd_skt, (struct sockaddr *)&sa_server, sizeof(sa_server)) ) 00084 while (true) { 00085 sa_len = sizeof(sa); 00086 ec_neg1( nrecv = recvfrom(fd_skt, msg, sizeof(msg), 0, 00087 (struct sockaddr *)&sa, &sa_len) ) 00088 if (nrecv != sizeof(msg)) { 00089 printf("server got short message\n"); 00090 break; 00091 } 00092 msg[0] = 'm'; 00093 ec_neg1( sendto(fd_skt, msg, sizeof(msg), 0, 00094 (struct sockaddr *)&sa, sa_len) ) 00095 } 00096 ec_neg1( close(fd_skt) ) 00097 exit(EXIT_SUCCESS); 00098 00099 EC_CLEANUP_BGN 00100 exit(EXIT_FAILURE); 00101 EC_CLEANUP_END 00102 } 00103 00104 int main(void) 00105 { 00106 int nclient; 00107 00108 strcpy(sa_server.sun_path, SOCKETNAME_SERVER); 00109 sa_server.sun_family = AF_UNIX; 00110 (void)unlink(SOCKETNAME_SERVER); 00111 for (nclient = 1; nclient <= 3; nclient++) 00112 run_client(nclient); 00113 run_server(); 00114 exit(EXIT_SUCCESS); 00115 }