problemas en una aplicación de chat basada en memoria compartida

Estoy tratando de crear una aplicación que tenga dos procesos que usen la memoria compartida para intercambiar mensajes... lo que estoy haciendo, como verán, es solicitar una memoria compartida y luego ponerle una estructura. la estructura consta de una cadena, un indicador Bool y una enumeración de valores... la cadena debe contener el mensaje, el indicador debe indicar si el otro lado ha visto o no este mensaje (porque nadie puede agregar un mensaje si hay es un mensaje no leído en la memoria) Tengo varios problemas 1- no puedo alcanzar la cadena en la cadena.... 2- cuando reemplacé la cadena con un int, tengo un problema en el lado del cliente al intentar para llegar a la memoria y este es el codigo...

Lado del servidor:

#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);

}

Lado del cliente:

#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);

}

Gracias de antemano, y perdon por el mal ingles.....

editar: gracias aix pero hay otro problema, es decir, el cliente primero no pudo obtener ningún dato de la memoria compartida, incluso cuando usé el int x para intercambiar números entre ellos, el cliente primero siguió dando 0 incluso cuando el servidor ha colocado otro valor , y después de un tiempo comenzó a darme un error al llamar a shmget();

editar (2): hice algunos cambios, pero todavía no funciona ...

Editar (3): Problema resuelto Gracias a todos, resultó ser un mal pedido de las banderas, gracias de nuevo ...

preguntado el 03 de mayo de 12 a las 11:05

Por lo general, es una buena idea ceñirse a los tipos de POD para la memoria compartida. -

2 Respuestas

El principal problema es que debajo de las sábanas std::string utiliza la asignación de almacenamiento dinámico.

Esto significa que

struct chat
{
   string  letter;

no coloca toda la cadena en la estructura. coloca la cuerda objeto, pero no necesariamente el datos de caracteres asociado con la cadena.

Una forma de solucionar esto es reemplazando std::string a char[N].

En general, se debe tener mucho cuidado al usar la memoria compartida con cualquier cosa que involucre punteros o referencias.

Además, para evitar complicaciones en torno a la construcción/destrucción, puede ser mejor asegurarse de que chat es un POD.

contestado el 03 de mayo de 12 a las 11:05

Hice lo que me dijiste, pero todavía no funciona... ni el cliente ni el servidor pueden leer desde la matriz de memoria compartida. HSN

Aconsejaría usar una biblioteca existente en lugar de recrear todo desde cero.

Por ejemplo: Impulsar el interproceso proporciona una Cola de mensajes.

Tenga en cuenta que los datos en la cola deben ser POD o usar el mecanismos de asignación entre procesos. Si es posible, le aconsejo serializando sus estructuras antes de escribirlas en la memoria compartida. Es más sencillo manejar la compatibilidad con versiones anteriores y posteriores de esta manera.

contestado el 03 de mayo de 12 a las 13:05

bueno, soy un poco nuevo en esto, estoy tratando de aprender, por eso prefiero empezar desde cero... - HSN

@HSN: En este caso, estaría tentado a recomendarle que eche un vistazo a la implementación de Boost... sin embargo, debo advertir que no es fácil de leer porque está repleto de soluciones para varios compiladores con errores. - Matthieu M.

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.