I’m trying to build an application that has two process that uses Shared memory to exchange messages…
what I’m doing as you will see , is requesting for a shared memory and then putting a struct in it .
the struct consist of a string , Bool flag and an enum values ..
the string should hold the message , the flag should tell whether this message has been seen or not by the other side (cause no one is allowed to add a message if there is a unread message in the memory )
I’m suffering from several problems
1- i cant reach the string at the string….
2- when i replaced the string with an int , i face a problem at the client side when trying to get to the memory
and this is the code …
Server’s side:
#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);
}
Client’s side:
#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);
}
Thanks in advance , and sorry for the bad English …..
edit:
thanks aix but there is another problem ,i.e the client first couldn’t get any data from the shared memory even when i used the int x to exchange numbers between them
the client first kept giving 0 even that the server has placed another value , and after a while it started giving me an error when calling shmget();
edit(2): i did some changes ,yet it still not working ….
Edit(3): Problem Solved Thank you all guys , turned out to be bad ordering to the flags
thanks Again …
The main problem is that under the covers
std::stringuses heap allocation.This means that
doesn’t place the entire string into the struct. It places the string object, but not necessarily the character data associated with the string.
One way to fix this is by replacing
std::stringwithchar[N].In general, extra care should be taken when using shared memory with anything that involves pointers or references.
Also, to avoid complications around construction/destruction, it may be best to make sure that
chatis a POD.