微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

基于共享内存的聊天应用程序出现问题

我正在尝试构build一个应用程序,该应用程序有两个使用共享内存交换消息的进程…我正在做的事情,您将会看到,正在请求共享内存,然后在其中放入一个结构体。 该结构由一个string,Bool标志和一个枚举值组成。string应该保存消息,该标志应该告诉对方是否已经看到这个消息(如果有的话,没有人允许添加消息是在内存中的未读消息)我遇到了几个问题1-我无法达到string的string…. 2-当我用一个intreplacestring,我在客户端时遇到问题去记忆,这是代码

服务器端:

#include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <iostream> #include <string> #include <sys/wait.h> using namespace std; enum e {Server,Client}; struct chat // struct that will reside in the memory { bool ifread; //boolian variable to determin if the message has been raed or not e who; char message[50]; int msgl; }; int main(void) { string temp; int shmid; //key_t key=ftok(".",'a'); key_t key=433; if ((shmid = shmget(key,sizeof(chat),IPC_CREAT | 0666)) < 0) { cout<<"shmget"<<endl; return(1); } chat *str ; str = (chat *)shmat(shmid,NULL,0); pid_t pid; pid=fork(); str->ifread==true; str->who=Server; if(pid==0) { while(temp!="bye") { if(str->ifread==false && str->who==Client) { //cout<<"Client said : "; for(int i=0;i<str->msgl;i++) cout<<str->message[i]; str->ifread==true; } } } else if (pid>0) { while(temp!="bye") { getline(cin,temp); str->msgl=temp.length(); if(str->ifread) { str->who=Server; for(int i=0;i<str->msgl;i++) { str->message[i]=temp.at(i); } str->who=Server; str->ifread==false; } else if (!str->ifread && str->who==Client) { sleep(1); waitpid(pid,0); } } } shmctl (shmid,IPC_RMID,NULL); }

客户方:

#include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <iostream> #include <string> #include <sys/wait.h> using namespace std; enum e {Server,'a'); key_t key=433; if ((shmid = s`hmget(key,0666)) < 0) { cout<<"shmget"<<endl; return(1); } chat *str ; str = (chat *)shmat(shmid,0); pid_t pid; pid=fork(); if(pid==0) { while(temp!="bye") { if(str->ifread==false && str->who==Server) { //cout<<"Server said : "; for(int i=0;i<str->msgl;i++) cout<<str->message[i]; str->ifread==true; } } } else if (pid>0) { while(temp!="bye") { getline(cin,temp); str->msgl=temp.length(); if(str->ifread) { str->who=Client; for(int i=0;i<str->msgl;i++) { str->message[i]=temp.at(i); } str->ifread=false; } else if (!str->ifread && str->who==Server) { sleep(1); //waitpid(pid,NULL); }

在此先感谢,并对不好的英语感到遗憾…..

在Linux中查找共享库的加载地址

DLL与不同的会话,服务和用户会话共享内存问题

等待任务运行? /任务完成时跳转下一行?

在不同的显示器上使用ubuntu共享opengl上下文

适用于Linux的支持NUMA的命名共享内存

编辑:谢谢aix,但还有一个问题,即客户端首先不能从共享内存中获取任何数据,即使当我使用int x交换他们之间的数字时,客户端第一次连续给出0,即使服务器已经放置了另一个值,过了一段时间,它开始给我一个错误,当调用shmget();

编辑(2):我做了一些改变,但它仍然无法正常工作….

编辑(3):解决问题谢谢大家,原来是不好的订购旗帜再次感谢…

Windows桌面共享api:如何共享一个应用程序

如何确定用户input是否是windows net share的有效共享名?

如何将共享button添加到Windows 10 Mobile UWP应用程序的CommandBar并共享它的function?

可移植的方式在不同的进程之间传递文件描述符

在多个龙卷风实例之间共享数据

主要的问题在于, std::string使用堆分配。

这意味着

struct chat { string letter;

不会将整个字符串放入结构中。 它放置字符串对象 ,但不一定是与字符串关联的字符数据 。

一种解决这个问题的方法是用char[N]替换std::string 。

一般来说,在使用共享内存时,应该特别注意任何涉及指针或引用的东西。

另外,为了避免造成/破坏的复杂性,最好确保chat是POD 。

我会建议使用现有的库,而不是从头重新创建所有的东西。

例如: Boost.Interprocess提供了一个消息队列 。

请注意,队列中的数据应该是POD或使用进程间分配机制 。 如果可能的话,我会建议序列化你的结构,然后写在共享内存中。 这样处理后向兼容性就更简单了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐