基于共享内存的聊天应用程序的问题
problems at a shared-memory based chat application
我正在尝试构建一个具有两个进程的应用程序,该进程使用共享内存来交换消息...正如您将看到的,我正在做的是请求共享内存,然后在其中放置一个结构。该结构由一个字符串、布尔标志和一个枚举值组成。字符串应该保存消息,标志应该告诉对方是否看到了这条消息(因为如果内存中有未读的消息,则不允许任何人添加消息(我遇到了几个问题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(( 时开始给我一个错误;
编辑(2(:我做了一些更改,但它仍然不起作用....
编辑(3(:问题已解决 谢谢大家,结果证明对标志的排序不好再次感谢...
主要问题是在幕后std::string
使用堆分配。
这意味着
struct chat
{
string letter;
不会将整个字符串放入结构中。它放置字符串对象,但不一定放置与字符串关联的字符数据。
解决此问题的一种方法是将std::string
替换为 char[N]
。
通常,将共享内存与涉及指针或引用的任何内容一起使用时应格外小心。
此外,为了避免施工/破坏方面的复杂情况,最好确保chat
是 POD。
我建议使用现有的库,而不是从头开始重新创建所有内容。
例如:Boost.Interprocess提供了一个消息队列。
请注意,队列中的数据应该是 POD 或使用进程间分配机制。如果可能的话,我建议在将结构写在共享内存中之前对其进行序列化。以这种方式处理向后和向前兼容性更简单。
- 试图在visual studio上用C++创建一个桌面应用程序
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 在C应用程序中运行C++(带有STL)函数
- 使用VerQueryValue检索应用程序的文件描述
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 使用调试/崩溃报告将应用程序部署到客户端
- C++控制台应用程序阻止退出
- 码头化的C++应用程序是否向后兼容早期的内核版本
- 将应用程序从32位移植到64位时出现问题
- 如何改变c++应用程序的视觉效果
- WM_CTLCOLORSTATIC从未在WIN32应用程序中触发
- PC中的程序和PHONE中的本机描述应用程序之间的数据连接
- C++客户端/服务器聊天应用程序 - 从 Ubuntu 命令窗口扫描输入
- 如何在桌面应用程序中使用WEBRTC进行语音聊天
- 聊天应用程序-从客户端连接到服务器时出现故障
- 两台具有相同 IP 地址的计算机 - 使用套接字的聊天应用程序
- 如何在小型聊天应用程序中为数据库存储的用户事务建模
- 如何在C++聊天应用程序中放置昵称
- C++迷你聊天应用程序
- 基于共享内存的聊天应用程序的问题