2012-05-03 2 views
2

Я пытаюсь создать приложение, которое имеет два процесса, которые используют общую память для обмена сообщениями ... что я делаю, как вы увидите, запрашивает общий памяти, а затем поместить в нее структуру. Структура состоит из строки, флага Bool и значений перечисления. строка должна содержать сообщение, флаг должен указывать, было ли это сообщение просмотрено или нет с другой стороны (поскольку никто не может добавить сообщение если в памяти есть непрочитанное сообщение) Я страдаю от нескольких проблем 1- i не могу получить строку в строке .... 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();

редактировать (2): я сделал некоторые изменения, но все еще не работает ....

Edit (3): Проблема решаемая Спасибо всем вам, ребята, как оказалось, плохо упорядоченность флагам спасибо Опять же ...

+2

Обычно рекомендуется придерживаться типов POD для общей памяти. –

ответ

4

Основная проблема заключается в том, что под обложками std::string используется распределение кучи.

Это означает, что

struct chat 
{ 
    string letter; 

не помещает всю строку в структуры. Он помещает строку объект, но необязательно данные символов , связанные со строкой.

Один из способов исправить это, заменив std::string на char[N].

В целом, при использовании общей памяти следует уделять особое внимание чему-либо, что связано с указателями или ссылками.

Кроме того, во избежание осложнений вокруг строительства/разрушения, лучше всего убедиться, что chat - это POD.

+0

aix, пожалуйста, проверьте изменения выше ... – HSN

+0

Я сделал, как вы мне сказали, но он все еще не работает ... ни клиент, ни сервер не могут читать из массива разделяемой памяти – HSN

1

Я бы посоветовал использовать существующую библиотеку, а не воссоздавать все с нуля.

Например: Boost.Interprocess содержит Message Queue.

Обратите внимание, что данные в очереди должны быть либо POD, либо использовать interprocess allocation mechanisms. Если возможно, я бы посоветовал сериализации ваших структур, прежде чем записывать их в общую память.Таким образом, проще обращаться с обратной и прямой совместимостью.

+0

ну, я вроде бы новичок в этом, я пытаюсь учиться, поэтому я предпочитаю начинать вещи из нуля ... – HSN

+0

@HSN: В этом случае у меня возникнет соблазн посоветовать вам заглянуть в реализацию Boost ... однако я должен предупредить, что это не так просто читать, потому что он загроможден для работы с различными компиляторами ошибок. –

Смежные вопросы