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