c - 消息队列中的内容已更改
问题描述
我在用uuntu 18.04.1LTS,用C学IPC。这次我用LPC测试Unix i/o,当多个客户端同时连接到服务器时会出现问题。(当只有一个客户端连接时,没有问题。)
sprintf(s1,"./%sA",t);
sprintf(s2, "./%sB", t);
if (MakeDirectory(s1, 0755) == -1) {
return -1;
}
if (MakeDirectory(s2, 0755) == -1) {
return -1;
}
for (i = 0; i < 5; i++)
{
memset(dirName, 0, SIZE);
sprintf(dirName, "%s/%d",s1,i);
usleep(300000);
if (MakeDirectory(dirName, 0755) == -1) {
return -1;
}
}
这段代码是客户端的主要功能。顶部没有问题,但是在运行一次repeat语句后(当i = 1时),MakeDirectory()返回-1并出错。(t 指的是转换为字符串的分叉进程的 pid。)
int MakeDirectory(char* path, int mode) {
memset(&pRequest, 0x00, LPC_REQUEST_SIZE);
memset(&pResponse, 0x00, LPC_RESPONSE_SIZE);
pRequest.pid = getpid();
pRequest.service = LPC_MAKE_DIRECTORY;
pRequest.numArg = 2;
pRequest.lpcArgs[0].argSize = strlen(path);
strcpy(pRequest.lpcArgs[0].argData, path);
pRequest.lpcArgs[1].argSize = mode;
msgsnd(rqmsqid, &pRequest, LPC_REQUEST_SIZE, 0);
msgrcv(rpmsqid, &pResponse, LPC_RESPONSE_SIZE, getpid(), 0);
int res = pResponse.responseSize;
return res;
}
这是客户的 MakeDirectory,并且
int MakeDirectory(LpcRequest* pRequest) {
memset(&pResponse, 0x00, LPC_RESPONSE_SIZE);
char *path = pRequest->lpcArgs[0].argData;
int mode = pRequest->lpcArgs[1].argSize;
int res = mkdir(path, mode);
pResponse.errorno = 0;
pResponse.pid = pRequest->pid;
printf("%ld\n", pResponse.pid);
pResponse.responseSize = res;
msgsnd(rpmsqid, &pResponse, LPC_RESPONSE_SIZE, 0);
return res;
}
这是在客户端启用 MakeDirectory 功能时,在检查 pRequest.service 后运行的服务器功能。
同样,拥有一个客户并没有错,如果客户不止一个。我检查了 printf(),但是服务器传递了 0,客户端收到了 -1。我不知道为什么会这样。
解决方案
您的代码中缺少太多内容,无法确切知道发生了什么。我押注要么使用未分配的内存,要么不识别系统调用错误。
我使用的是 LTS 16,我的系统上没有 LpcRequest 或 LPC_REQUEST_SIZE 等的定义。你没有展示它们是如何定义的,所以我们不知道例如是否pRequest.lpcArgs[1]
存在。
您也没有检查 msgsnd 和 msgrcv 的返回码,这无疑是无休止的娱乐调试的秘诀。
我建议您编辑您的问题以包含工作代码和产生神秘结果的 shell 脚本。然后,如果愿意,有人将能够调试它并解释你哪里出错了。
我在这方面的另一个建议是相当标准的:W. Richard Stevens 的 TCP/IP 书籍,特别是Unix Network Programming。如果你正在研究这些东西,你绝对会很高兴读到它。
推荐阅读
- java - 我已经创建了 chrome 驱动程序对象,然后我得到了 java.lang.NullPointerException
- java - 在 Sceneform 中拍照时隐藏 PlaneRenderer
- scala - 在@FXML 变量绑定之前调用'initialize'
- python-3.x - 运行 OpenCV 和 imutils 的属性错误
- javascript - 在 javaScript 中使用 == 运算符时,如何证明布尔数据类型转换为数字
- angular - Angular 5 ngForm:无法验证表单提交时的选择框选项
- c++ - C++ 可以将基类转换回派生类吗?
- gradle - Gradle:在哪里可以找到一些关于 gradle 缓存目录的教程
- java - 它是 Selenium 文档中的错误吗?
- jquery - Jquery .find() 在表中返回未定义