2012-05-03 17 views
2

共有メモリを使用してメッセージを交換する2つのプロセスを持つアプリケーションを構築しようとしています... あなたが見ているように、共有をリクエストしていますそれから構造体を入れます。 構造体は文字列、ブールフラグ、列挙型の値で構成されます。 文字列はメッセージを保持するはずです。フラグは、このメッセージが他の側で見られたかどうかを示すはずです(誰もメッセージを追加できないためメモリに未読のメッセージがある場合) 私はいくつかの問題を抱えています 1文字列の文字列に到達できません。 2文字列をintに置き換えたとき、私は問題に直面します。 ...メモリ に取得しようと、これはコードで、クライアント側共有メモリベースのチャットアプリケーションでの問題

Serverの側:

#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):問題解決あなたのすべての皆さんに感謝、感謝 フラグに悪い順序であることが判明再び...

+2

通常、共有メモリのPODタイプに固執することをお勧めします。 –

答えて

4

主な問題は、カバーの下でstd::stringがヒープ割り当てを使用することです。

これは

struct chat 
{ 
    string letter; 

は、構造体の中に文字列全体を配置しないことを意味します。文字列オブジェクトを配置しますが、必ずしも文字データを文字列に関連付ける必要はありません。

これを修正する方法の1つは、std::stringchar[N]に置き換えることです。

一般に、共有メモリにポインタや参照を含むものを使用する場合は、細心の注意が必要です。

また、建設/破壊の問題を避けるために、chatPODであることを確認することをお勧めします。

+0

AIX、このようなものにちょっと新しいイム、あなたが私に言った、まだそれはまだ動作していないと私は... クライアントとサーバーのいずれも、うまく共有メモリアレイ – HSN

+0

を編集をご確認ください。私が学ぶことを試みているので、私はフォームゼロから物事を始めるのが好きなのです... – HSN

1

すべてをゼロから再作成するのではなく、既存のライブラリを使用することをお勧めします。

たとえば、Boost.Interprocessは、Message Queueです。

キュー内のデータはPODであるか、interprocess allocation mechanismsを使用する必要があります。可能であれば、シリアライズして共有メモリに書き込むことをお勧めします。この方法で後方互換性と前方互換性を処理する方が簡単です。

+0

から読み取ることができなかった...上記 – HSN

+0

@HSN:この場合、Boostの実装を覗いてみるようアドバイスしたいと思います...しかし、さまざまなバグのあるコンパイラの回避策がたくさんあるので、読みにくいです。 –

関連する問題