用socket(基于tcp协议)进行本地间多进程通信

本地进程:ipc server为服务端,维护一组连接进来的客户端socket fd,把每个客户端发过来的数据判断是服务器已经订阅的消息就分发到全部连接进来的客户端.

本地进程:ipc client1为客户端1,客户端1连接服务端,并接受服务端分发的数据,判断该数据是否是自己需要的数据(订阅的数据),如果是就做出处理,否则扔掉.

本地进程:ipc client2为客户端2,客户端2连接服务端,并接受服务端分发的数据,判断该数据是否是自己需要的数据(订阅的数据),如果是就做出处理,否则扔掉.

本地进程:ipc client3为客户端3,客户端3连接服务端,并接受服务端分发的数据,判断该数据是否是自己需要的数据(订阅的数据),如果是就做出处理,否则扔掉.

......

客户端1与客户端3需要通信,则客户端1需要先订阅客户端3有关信息,客户端3发布数据(包含客户端1订阅的有关信息)到ipc server,ipc server分发到所有客户端,客户端1收到数据,判断数据,发现是已订阅客户端3的有关信息,做出相应处理.客户端2没有订阅,则扔掉数据.

......

其他客户端用类似方式进行进程通信,订阅的信息可以作为数据头拼接进数据包,客户端收到分发的数据,解析出数据头并与订阅信息比较,调用函数处理.

(server可以将消息类型与数据都分发到客户端,客户端根据消息类型,如果是已订阅消息类型就将数据(包含消息类型)传到一个回调函数,回调函数根据消息类型进行处理.代码未实现)

代码实现(由于时间原因,写得比较简陋与粗糙):

ipc server端:

 

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<sys/socket.h>
  5 #include<netinet/in.h>
  6 #include<arpa/inet.h>
  7 #include<unistd.h>
  8 #include<pthread.h>
  9 #include<sys/select.h>
 10 #include<sys/time.h>
 11 #include<vector>
 12 using  namespace std;
 13 vector<int>sockfds;
 14 vector<int>subscribes;
 15 int my_sock_fd;
 16 pthread_mutex_t mtx;
 17 void* read_thread(void *arg);
 18 void read_run(int sockfd);
 19 void read_run(int sockfd)
 20 {
 21     pthread_t thread;
 22     my_sock_fd=sockfd;
 23     if(pthread_create(&thread, NULL,read_thread, NULL)!=0)//创建子线程  
 24     {  
 25         perror("pthread_create error");  
 26     }
 27     else
 28     {
 29         printf("pthread_create success\n");
 30     } 
 31 }
 32 void* read_thread(void *arg)
 33 {
 34     int sock_fd=my_sock_fd;
 35     printf("read_thread sock_fds:%d\n",sock_fd);
 36     while(1)
 37     {  
 38         char buf[100] = {0};
 39         int ret=-1;
 40         
 41         ret = read(sock_fd,buf,sizeof(buf));
 42         if(ret>0)
 43         {    
 44             printf("接受了%d字节,内容:%s\n",ret,buf);
 45             if(buf[0]=='%'&&buf[1]=='%')//订阅消息
 46             {
 47                 bool pushsub=true;
 48                 printf("client subscribe msg is:[%c]\n",buf[2]);
 49                 for(vector<int>::iterator it=subscribes.begin();it!=subscribes.end();it++)
 50                 {
 51                    if(*it==buf[2])
 52                    {
 53                         pushsub=false;
 54                    }
 55                 }
 56                 if(pushsub==true)
 57                     subscribes.push_back(((int)buf[2]));
 58                 printf("all subscribes msg:\n");
 59                 for(vector<int>::iterator it=subscribes.begin();it!=subscribes.end();it++)
 60                 {
 61                    printf("[%c] ",*it);
 62                 }
 63                 printf("\n");
 64             }
 65             else if(buf[0]=='$'&&buf[1]=='$')//取消订阅消息
 66             {
 67                 printf("client cancel subscribe msg is:");
 68                 for(vector<int>::iterator it=subscribes.begin();it!=subscribes.end();it++)
 69                 {
 70                   if(*it==buf[2])
 71                   {
 72                        printf("[%c]\n",*it);
 73                        subscribes.erase(it);
 74                        break;
 75                   }
 76                }
 77                 printf("all subscribes msg:");
 78                 for(vector<int>::iterator it=subscribes.begin();it!=subscribes.end();it++)
 79                 {
 80                      printf("[%c] ",*it);
 81                 }
 82                 printf("\n"); 
 83             }
 84             else
 85             {
 86                 for(vector<int>::iterator sit=subscribes.begin();sit!=subscribes.end();sit++)//分发消息
 87                 {
 88                     if(*sit==buf[0])
 89                     {
 90                         for(vector<int>::iterator it=sockfds.begin();it!=sockfds.end();it++)
 91                         {
 92                             printf("write sock_fds:%d\n",*it);
 93                             int res=write(*it,buf,99);
 94                             printf("write %d byte\n",res);
 95                         }
 96                     }
 97 
 98                 }
 99             }
100 
101         }
102         if(ret==0)
103         {
104             for(vector<int>::iterator it=sockfds.begin();it!=sockfds.end();it++)
105            {      
106                 if(*it==sock_fd)
107                 {
108                     pthread_mutex_lock(&mtx);
109                     printf("close sock_fds:%d\n",sock_fd);
110                     sockfds.erase(it);
111                     close(sock_fd);
112                     pthread_mutex_unlock(&mtx);
113                     break;
114                 }
115            } 
116             printf("after erase all sock_fds: ");
117             for(vector<int>::iterator it=sockfds.begin();it!=sockfds.end();++it)
118             {    
119                 printf("%d ",*it);
120             }
121                 printf("\n");
122             break; 
123             }  
124     }
125 }
126 int main()
127 {
128     pthread_mutex_init(&mtx, NULL);
129     int sockfd = socket(AF_INET,SOCK_STREAM,0);
130     if (sockfd == -1)
131     {
132         perror("socket"),exit(-1);
133     }
134     for(int i='a';i<='b';i++)//默认订阅消息[a]与[b]
135     subscribes.push_back(i);
136     struct sockaddr_in addr;
137     addr.sin_family = AF_INET;
138     addr.sin_port = htons(12222);
139     addr.sin_addr.s_addr = inet_addr("127.0.0.1");
140     int res = bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));
141     if (res == -1)
142     {
143         perror("bind\n");
144         exit(-1);
145     }
146     printf("bind ok\nwait client connect...\n");
147     listen(sockfd,100);//监听
148     struct sockaddr_in client;
149     socklen_t len = sizeof(client);
150     printf("input [exit] and press Ctrl+C exit this program\n");
151     while(1)
152     {
153         int fd = accept(sockfd,(struct sockaddr*)&client,&len);
154         char *from = inet_ntoa(client.sin_addr);//十六进制转点分十进制
155         printf("%s is connected\n",from);
156         pthread_mutex_lock(&mtx);
157         sockfds.push_back(fd); 
158         pthread_mutex_unlock(&mtx);          
159         printf("sock_fds.push_back:%d\n",fd);
160         read_run(fd);
161         printf("after accept all sock_fds:");
162         for(vector<int>::iterator it=sockfds.begin();it!=sockfds.end();++it)
163         {    
164             printf("%d ",*it);
165         }
166         printf("\n");
167     }
168     close(sockfd);
169     return 0;
170 }

 

ipc client端:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<unistd.h>
  5 #include<sys/socket.h>
  6 #include<netinet/in.h>
  7 #include<arpa/inet.h>
  8 #include<pthread.h>
  9 #include<vector>
 10 bool exit_thread=false;
 11 int sockfd ;
 12 using namespace std;
 13 vector<int>subscribes;
 14 void read_run();
 15 void* read_thread(void* arg);
 16 void read_run()
 17 {
 18     pthread_t thread;
 19     if(pthread_create(&thread, NULL,read_thread, NULL)!=0)  
 20     {  
 21         perror("pthread_create error");  
 22     }
 23     else
 24     {
 25         printf("pthread_create \n");
 26     } 
 27 }
 28 void* read_thread(void *arg)
 29 {
 30     while(1)
 31     {    
 32              if(exit_thread==true)
 33              {
 34                  break;
 35              }
 36             char buf[100] = {0};
 37             int ret=-1;
 38             ret = read(sockfd,buf,sizeof(buf));
 39             if(ret>0)
 40             {   
 41                 for(vector<int>::iterator it=subscribes.begin();it!=subscribes.end();it++)
 42                 {
 43                     if(*it==buf[0])
 44                     {
 45                         char tmp[99];
 46                         memcpy(tmp,buf+1,99);
 47                         printf("接受了%d字节,内容:%s\n",ret-1,tmp);
 48                     }
 49                 } 
 50                
 51             }
 52     }
 53 }
 54 int main(){
 55     sockfd = socket(AF_INET,SOCK_STREAM,0);
 56     if (sockfd == -1){
 57         perror("socket"),exit(-1);
 58     }
 59     int i;
 60     for(i='a';i<='b';i++)//默认订阅消息[a]与[b]
 61     subscribes.push_back(i);
 62     struct sockaddr_in addr;
 63     addr.sin_family = AF_INET;
 64     addr.sin_port = htons(12222);
 65     addr.sin_addr.s_addr = inet_addr("127.0.0.1");
 66     int res = connect(sockfd,(struct sockaddr*)&addr,
 67             sizeof(addr));
 68     if (res == -1){
 69         perror("connect"),exit(-1);
 70     }
 71     printf("连接成功\n");
 72     printf(",发送消息时注意:[%%]与[$$]用作服务端判断订阅与取消订阅类型的消息头\n");
 73     read_run();
 74     while(1)
 75     {
 76         char buffer[100];
 77         char input;
 78         char ch;
 79         printf("输入\n[1]:发送消息\n[2]:增加订阅消息到服务器\n[3]:取消服务器已订阅消息\n[4]:增加本地订阅消息\n[5]:取消本地已订阅消息\n[6]:退出\n");
 80         scanf("%c",&input);
 81         while ((ch = getchar()) != '\n')
 82         {
 83             ;
 84         }
 85         switch (input)
 86         {
 87         case '1':
 88                    {
 89                         printf("发送消息类型(与订阅消息相关,一个字符),按下enter输入\n");
 90                         scanf("%c",&input);
 91                         while ((ch = getchar()) != '\n')
 92                         {
 93                              ;
 94                         }
 95                         printf("输入发送消息,按下enter键发送\n");
 96                         memcpy(buffer,&input,1);
 97                         scanf("%s",buffer+1);
 98                         while ((ch = getchar()) != '\n')
 99                         {
100                              ;
101                         }
102                         write(sockfd,(void *)&buffer,100);
103                     }
104 
105             break;
106         case '2':
107                 {
108                     {
109                         printf("输入订阅消息(一个字符),按下enter键发送\n");
110                         scanf("%c",&input);
111                          while ((ch = getchar()) != '\n')
112                         {
113                              ;
114                         }
115                         memcpy(buffer,"%%",2);
116                         memcpy(buffer+2,&input,1);
117                         write(sockfd,(void *)&buffer,100);
118                     }
119                 }
120             break;
121         case '3':
122                 {
123                     {
124                         printf("输入取消订阅消息(一个字符),按下enter键发送\n");
125                         scanf("%c",&input);
126                         while ((ch = getchar()) != '\n')
127                         {
128                              ;
129                         }
130                         memcpy(buffer,"$$",2);
131                         memcpy(buffer+2,&input,1);
132                         write(sockfd,(void *)&buffer,100);
133                     }
134                 }
135             
136             break;
137         case '6':
138                     {
139                         printf("exiting...\n");
140                         exit_thread=true;
141                         close(sockfd);
142                         printf("exit success\n");
143                         return 0;
144                     }
145             break;
146                     case '4':
147                 {
148                     {
149                         printf("输入订阅消息(一个字符),按下enter键增加订阅\n");
150                         scanf("%c",&input);
151                          while ((ch = getchar()) != '\n')
152                         {
153                              ;
154                         }
155                         bool pushsub=true;
156                         for(vector<int>::iterator it=subscribes.begin();it!=subscribes.end();it++)
157                         {
158                             if(*it==input)
159                             {
160                                 pushsub=false;
161                             }
162                         }
163                         if(pushsub==true)
164                         subscribes.push_back(((int)input));
165                         printf("all subscribes msg:\n");
166                         for(vector<int>::iterator it=subscribes.begin();it!=subscribes.end();it++)
167                         {
168                            printf("[%c] ",*it);
169                         }
170                         printf("\n");
171                     }
172                 }
173             break;
174         case '5':
175                 {
176                      printf("输入取消订阅消息(一个字符),按下enter键取消订阅\n");
177                     scanf("%c",&input);
178                     while ((ch = getchar()) != '\n')
179                     {
180                         ;
181                     }
182                     printf("client cancel subscribe msg is:");
183                     for(vector<int>::iterator it=subscribes.begin();it!=subscribes.end();it++)
184                     {
185                         if(*it==input)
186                         {
187                             printf("[%c]\n",*it);
188                             subscribes.erase(it);
189                             break;
190                         }
191                     }
192                     printf("all subscribes msg:");
193                     for(vector<int>::iterator it=subscribes.begin();it!=subscribes.end();it++)
194                     {
195                         printf("[%c] ",*it);
196                     }
197                         printf("\n"); 
198                     }
199             
200             break;
201              
202         default:
203             break;
204         }
205     }
206     return 0;
207 }
posted @ 2019-09-01 22:16  jest549  阅读(956)  评论(0编辑  收藏  举报