多个客户端与服务器端发送消息案例

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

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

注意:

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

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

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

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

代码:

客户端:

      #include <stdio.h>  
      #include <stdlib.h>  
      #include <fcntl.h>  
      #include <sys/ipc.h>  
      #include <sys/msg.h>  
      #include <string.h>  
       
     //消息队列发送数据的要求,以一个结构体  
     struct mybuf  
     {  
         long channel;//通道号  
         char mtext[100];//一块缓冲区,装发送数据  
     };  
       
     int main()  
     {  
         int id=msgget(1234,0);//打开1234这个消息队列  
         if(id==-1)  
         {  
             perror("msgget\n");  
             exit(1);  
         }  
         struct mybuf buf;//在内存中创建一个用来传递消息的结构体  
       
         //客户端  
         while(1)  
         {  
             memset(&buf,0x00,sizeof(buf));  
             //首先客户端要发送内容到1号通道  
             buf.channel=1;  
             //把要发送的内容前面放成自己的进程号  
             *(long*)buf.mtext=(long)getpid();  
             printf("请输入要发送的消息:");  
             scanf("%s",buf.mtext+sizeof(long));//把要发送的内容输入到buf对应的位置  
             //发送  
             msgsnd(id,&buf,strlen(buf.mtext+sizeof(long))+sizeof(long),0);  
             //每次接受前,读取前,清空缓冲区  
             memset(&buf,0x00,sizeof(buf));  
             //接受从自己进程号作为通道的信息  
             msgrcv(id,&buf,100,getpid(),0);  
             printf("客户端接受:%s\n",buf.mtext + sizeof(long) );  
       
         }  
       
         return 0;  
     }  

服务器端:

  #include <stdio.h>  
  #include <stdlib.h>  
  #include <fcntl.h>  
  #include <sys/ipc.h>  
  #include <sys/msg.h>  
  #include <string.h>  
    
 //消息队列发送数据的要求,以一个结构体  
 struct mybuf  
 {  
     long channel;//通道号  
     char mtext[100];//一块缓冲区,装发送数据  
 };  
   
 int main()  
 {  
     int id=msgget(1234,IPC_CREAT|0644);//打开1234这个消息队列  
     if(id==-1)  
     {  
         perror("msgget\n");  
         exit(1);  
     }  
     struct mybuf buf;//在内存中创建一个用来传递消息的结构体  
   
     //服务器  
     while(1)  
     {  
         memset(&buf,0x00,sizeof(buf));//清空缓冲区  
   
         //服务器从id这个消息队列的1号通道接受100大小数据放在buf中,没数据等待  
         msgrcv(id,&buf,100,1,0);  
     //服务器接受到客户端发来的内容,要从其中解析出客户端的进程号,以备返回给该进程  
         buf.channel=*(long*)buf.mtext;  
         msgsnd(id,&buf,strlen(buf.mtext+sizeof(long))+sizeof(long),0);  
         printf("fu send is ok\n");  
     }  
   
     return 0;  
 }  


全部评论

相关推荐

02-07 12:06
已编辑
华侨大学 测试开发
最近看到很多&nbsp;92&nbsp;的,甚至是硕士,开始往测开赛道卷,说实话有点看不懂。先把话说清楚,大厂里的测开,绝大多数时间干的还是测试的活,只是写点自动化脚本、维护测试平台、接接流水线,真正像开发一样做系统、做架构、做核心平台的测开少得可怜,基本都集中在核心提效组,而且人很少,外面进去的大概率轮不到你,我想真正干过人都清楚。很多人被洗脑了,以为测开也是开,和后端差不多,只是更简单、更轻松、还高薪。现实情况是,测开和开发的职业路径完全不一样。开发的核心是业务和系统能力,测开的核心是稳定性和覆盖率,前者是往上走,后者天花板非常明显。你可以见到很多开发转测开,但你很少见到干了几年测开还能顺利转回开发的。更现实一点说,92&nbsp;的高学历如果拿来做测开,大部分时间就是在做重复性很强的杂活,这种工作对个人能力的放大效应非常弱。三年下来,你和一个双非的,甚至本科的测开差距不会太大,但你和同龄的后端、平台开发差距会非常明显。这不是努不努力的问题,是赛道问题。所谓测开简单高薪,本质上是把极少数核心测开的上限,当成了整个岗位的常态来宣传。那些工资高、技术强的测开,本身就是开发水平,只是挂了个测开的名。普通人进去,99%&nbsp;做的都是项目兜底型工作,而不是你想象中的平台开发。测开不是不能做,但它绝对不是开发的平替,也不是性价比最优解。如果你是真的不想做开发,追求稳定,那测开没问题。但如果你只是觉得测开比后端容易,还能进大厂,那我劝你冷静一点,这只是在用短期安全感换长期天花板。有92的学历,如果你连测开这些重复性工作都能心甘情愿接受,那你把时间精力用在真正的开发、系统、业务深度上,回报大概率比卷测开要高得多。想清楚再下场,别被岗位名和话术带偏了,就算去个前端客户端也是随便占坑的,测开是一个坑位很少赛道,反而大面积学历下放,不用想也能知道会是什么结果,我想各位在JAVA那里已经看到了
小浪_Coding:工作只是谋生的手段 而不是相互比较和歧视
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务