linux - IPC 使用 msgsnd 和 msgrcv

标签 linux ipc message-passing

为了学习,我写了 2 个 IPC 程序,一个服务器和一个使用消息发送的客户端。由于某种原因,服务器似乎没有收到它已发送的数据。关于如何调试此类问题,您能给我一些提示吗?

#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define CENTRAL_MAILBOX 1200
#define CLIENT_MAILBOX 1201

struct {
long priority;
int value;
int pid;
} msgp, cmbox;

int main(int argc, char **argv) {

int uid = 0; // Process id of the server(this process) set to 0
int length = -1; // Length of the structure we are going to send over
int result = -1; // Result of the msgrcv operation
int status = -1;

if ( argc != 2 ) {
    fprintf(stderr, "Usage: ./server <temperature>\n");
    exit(-1);
}

printf("[+] Starting server\n");

printf("[+] Creating the mailbox\n");
int server_msgid = msgget(CENTRAL_MAILBOX, 0600 | IPC_CREAT);

printf("[+] Creating a mailbox for the client process\n");
int client_msgid = msgget(CLIENT_MAILBOX, 0600 | IPC_CREAT);

printf("[+] Initializing data to be sent across\n");
msgp.priority = 1;
msgp.value = 31337;
msgp.pid = uid;

length = ( sizeof(msgp) > sizeof(long) ? sizeof(msgp)-sizeof(long) : sizeof(long)-sizeof(msgp) );
printf("[+] Calculating the size of the message we are about to send across=%d\n", length);

// msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
result = msgrcv(server_msgid, &cmbox, length, 1, 0);
printf("Result = %d\n", result);
printf("[+] Received message pid=%d, value=%d, priority=%ld\n", cmbox.pid, cmbox.value, cmbox.priority);

printf("[+] Sending message\n");
// int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
result = msgsnd(client_msgid, &msgp, length, 0);

printf("[+] Shutting down server\n");
status = msgctl(server_msgid, IPC_RMID, 0);

if ( status != 0 ) {
fprintf(stderr, "[*] ERROR: closing mailbox failed\n");
}

}

我的客户:-

#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define CENTRAL_MAILBOX 1200
#define CLIENT_MAILBOX 1201

struct {
long priority;
int value;
int pid;
} msgp, cmbox;

int main(int argc, char **argv) {

int temp = atoi(argv[1]);
int uid = getpid(); //7171;
int length, result, status;

if ( argc != 2 ) {
// TODO find actual process id
fprintf(stderr, "Usage: ./client <temperature>\n");
exit(-1);
}

printf("[+] Creating server mailbox\n");
int server_msgid = msgget(CENTRAL_MAILBOX, 0600 | IPC_CREAT);

printf("[+] Creating client mailbox\n");
int client_msgid = msgget(CLIENT_MAILBOX, 0600 | IPC_CREAT);

printf("[+] Initializing the data to be sent across\n");
cmbox.priority = 2;
cmbox.value = 1337;
cmbox.pid = uid;

length = ( sizeof(msgp) > sizeof(long) ? sizeof(msgp)-sizeof(long) : sizeof(long)-sizeof(msgp) );
printf("[+] Calculating the size of the message we are about to send across=%d\n", length);

printf("[+] Sending message to server\n");
result = msgsnd(server_msgid, &cmbox, length, 0);
printf("Result = %d\n", result);

result = msgrcv(client_msgid, &msgp, length, 1, 0);
printf("[+] Received message pid=%d, value=%d, priority=%ld\n", msgp.pid, msgp.value, msgp.priority);

printf("[+] Removing the mailbox\n");
status = msgctl(client_msgid, IPC_RMID, 0);

if ( status != 0 ) {
printf("Error when closing mailbox\n");
}

}

最佳答案

您的服务器在 1 日阻塞 msgrcv() 因为它需要类型 1 的消息(您在 msgp, cmbox 结构中称为优先级):

// msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
result = msgrcv(server_msgid, &cmbox, length, 1, 0);

当客户端发送类型2的消息时:

printf("[+] Initializing the data to be sent across\n");
cmbox.priority = 2;

// [...]

printf("[+] Sending message to server\n");
result = msgsnd(server_msgid, &cmbox, length, 0);

看看如何使用手册页中的 msgtyp 值:

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

[...]

The msgp argument is a pointer to caller-defined structure of the following general form:

struct msgbuf {
    long mtype;       /* message type, must be > 0 */
    char mtext[1];    /* message data */
};

[...]

msgrcv()

[...]

The argument msgtyp specifies the type of message requested as follows:

  • If msgtyp is 0, then the first message in the queue is read.
  • If msgtyp is greater than 0, then the first message in the queue of type msgtyp is read, unless MSG_EXCEPT was specified in msgflg, in which case the first message in the queue of type not equal to msgtyp will be read.
  • If msgtyp is less than 0, then the first message in the queue with the lowest type less than or equal to the absolute value of msgtyp will be read.

关于linux - IPC 使用 msgsnd 和 msgrcv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16794410/

相关文章:

c# - 如何从其 Win32 句柄中获取 System.Windows.Form 实例?

linux - 在查找命令中排除子路径

c - 如何在 C 的目录/子目录中查找文件的实例?

linux - 写入包含 5 个以上文件的子目录的 Bash 脚本

rpc - RPC 在消息传递方面的缺点是什么?

objective-c - 如何使用 Obj-C Blocks 实现 whileTrue 控制流方法?

c++ - 两个程序之间的消息传递

c - Linux 上的汇编编译器。纳斯姆还是AS?

objective-c - 使用分布式对象的进程之间的通信

c# - 命名管道 C# 服务器 C++ .dll 客户端不工作?