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

我正在尝试构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,NULL,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,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 = s`hmget(key, sizeof(chat), 0666)) < 0) { cout<<"shmget"<<endl; return(1); } chat *str ; str = (chat *)shmat(shmid, NULL, 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,0); } } } shmctl (shmid, IPC_RMID, NULL); } 

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

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

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

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

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

这意味着

 struct chat { string letter; 

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

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

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

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

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

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

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