【问题标题】:problems at a shared-memory based chat application基于共享内存的聊天应用程序的问题
【发布时间】:2012-05-12 20:39:19
【问题描述】:

我正在尝试构建一个具有两个使用共享内存交换消息的进程的应用程序... 正如您将看到的,我正在做的是请求共享内存,然后在其中放入一个结构。 该结构由一个字符串、布尔标志和一个枚举值组成。 字符串应该保存消息,标志应该告诉对方是否看到了这条消息(因为如果内存中有未读消息,则不允许任何人添加消息) 我遇到了几个问题 1-我无法到达字符串处的字符串.... 2-当我用 int 替换字符串时,我在尝试访问内存时在客户端遇到问题 这是代码...

服务器端:

#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() 时它开始给我一个错误;

edit(2):我做了一些更改,但仍然无法正常工作....

编辑(3):问题已解决谢谢大家,结果是对标志的排序不正确 再次感谢...

【问题讨论】:

  • 通常最好坚持使用 POD 类型来共享内存。

标签: c++ linux memory shared-memory shared


【解决方案1】:

主要问题是std::string 使用堆分配。

这意味着

struct chat
{
   string  letter;

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

解决此问题的一种方法是将std::string 替换为char[N]

通常,在将共享内存用于涉及指针或引用的任何内容时,应格外小心。

另外,为了避免构造/销毁的复杂性,最好确保chatPOD

【讨论】:

  • 我照你说的做了,但还是不行……客户端和服务器都不能从共享内存数组中读取数据
【解决方案2】:

我建议使用现有的库,而不是从头开始重新创建所有内容。

例如:Boost.Interprocess 提供了一个Message Queue

请注意,队列中的数据应该是 POD 或使用 interprocess allocation mechanisms。如果可能的话,我会建议在将它们写入共享内存之前序列化你的结构。以这种方式处理向后和向前兼容性更简单。

【讨论】:

  • 嗯,我对这些东西有点陌生,我正在努力学习,所以这就是为什么我更喜欢从零开始......
  • @HSN:在这种情况下,我很想建议你看一下 Boost 的实现......但是我应该警告它不容易阅读,因为它的解决方法很混乱各种错误的编译器。
猜你喜欢
  • 2017-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
  • 2023-01-20
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
相关资源
最近更新 更多