欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

许多客户端与服务器端通信的小案例

程序员文章站 2022-03-15 22:23:48
...

案例:用消息队列实现许多客户端和服务器端的通信,要求是,许多客户端都可以向服务器端发送消息,服务器端在接受这些消息之后,再将消息回发给对应的客户端。

解决思路:所有客户端都往1号通道上发送消息,并且在发送的内容的最前面放上自己进程的进程号,那么当服务器端收到中众多客户端发来的消息之后,通过解析主要内容的最前面内容,拿出对应客户端进程号,将其作为发送通道发送给对应的客户端,那么客户端接受的消息就来自以自己进程号为通道号的消息,服务器在1号通道等待接受数据,没有数据就阻塞。

注意:

1)发送消息的,提前设定要发的通道号(buf.channel=1,就说明要发送的通道号是1号);而接受消息时直接将接受通道号作为参数传过去。

2)每次接受前,读前都要刷新缓冲区

3)因为客户端把自己的进程号放在发送消息的前面,(假如是进程号为3,0011,小端存储1100,那么用strlen()计算长度,遇到0会结束,因此用巧妙手

段:strlen(buf.mtext+sizeof(long))+sizeof(long),0)

代码:

客户端:

 4 #include <stdio.h>
  5 #include <stdlib.h>
  6 #include <fcntl.h>
  7 #include <sys/ipc.h>
  8 #include <sys/msg.h>
  9 #include <string.h>
 10 
 11 //消息队列发送数据的要求,以一个结构体
 12 struct mybuf
 13 {
 14     long channel;//通道号
 15     char mtext[100];//一块缓冲区,装发送数据
 16 };
 17 
 18 int main()
 19 {
 20     int id=msgget(1234,0);//打开1234这个消息队列
 21     if(id==-1)
 22     {
 23         perror("msgget\n");
 24         exit(1);
 25     }
 26     struct mybuf buf;//在内存中创建一个用来传递消息的结构体
 27 
 28     //客户端
 29     while(1)
 30     {
 31         memset(&buf,0x00,sizeof(buf));
 32         //首先客户端要发送内容到1号通道
 33         buf.channel=1;
 34         //把要发送的内容前面放成自己的进程号
 35         *(long*)buf.mtext=(long)getpid();
 36         printf("请输入要发送的消息:");
 37         scanf("%s",buf.mtext+sizeof(long));//把要发送的内容输入到buf对应的位置
 38         //发送
 39         msgsnd(id,&buf,strlen(buf.mtext+sizeof(long))+sizeof(long),0);
 40         //每次接受前,读取前,清空缓冲区
 41         memset(&buf,0x00,sizeof(buf));
 42         //接受从自己进程号作为通道的信息
 43         msgrcv(id,&buf,100,getpid(),0);
 44         printf("客户端接受:%s\n",buf.mtext + sizeof(long) );
 45 
 46     }
 47 
 48     return 0;
 49 }

服务器端:

 3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include <fcntl.h>
  6 #include <sys/ipc.h>
  7 #include <sys/msg.h>
  8 #include <string.h>
  9 
 10 //消息队列发送数据的要求,以一个结构体
 11 struct mybuf
 12 {
 13     long channel;//通道号
 14     char mtext[100];//一块缓冲区,装发送数据
 15 };
 16 
 17 int main()
 18 {
 19     int id=msgget(1234,IPC_CREAT|0644);//打开1234这个消息队列
 20     if(id==-1)
 21     {
 22         perror("msgget\n");
 23         exit(1);
 24     }
 25     struct mybuf buf;//在内存中创建一个用来传递消息的结构体
 26 
 27     //服务器
 28     while(1)
 29     {
 30         memset(&buf,0x00,sizeof(buf));//清空缓冲区
 31 
 32         //服务器从id这个消息队列的1号通道接受100大小数据放在buf中,没数据等待
 33         msgrcv(id,&buf,100,1,0);
 34     //服务器接受到客户端发来的内容,要从其中解析出客户端的进程号,以备返回给该进程
 35         buf.channel=*(long*)buf.mtext;
 36         msgsnd(id,&buf,strlen(buf.mtext+sizeof(long))+sizeof(long),0);
 37         printf("fu send is ok\n");
 38     }
 39 
 40     return 0;
 41 }