IPC с использованием msgsnd и msgrcv
Для обучения я написал 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 ответ
Ваш сервер блокирует на 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);
[...]
msgp
Аргумент является указателем на определяемую вызывающей структурой следующую общую форму:struct msgbuf { long mtype; /* message type, must be > 0 */ char mtext[1]; /* message data */ };
[...]
msgrcv()
[...]
Аргумент
msgtyp
определяет тип запрашиваемого сообщения следующим образом:
- Если
msgtyp
0, то первое сообщение в очереди читается.- Если
msgtyp
больше 0, то первое сообщение в очереди типаmsgtyp
читается, еслиMSG_EXCEPT
был указан вmsgflg
в этом случае первое сообщение в очереди типа не равноmsgtyp
будет прочитано- Если
msgtyp
меньше 0, то первое сообщение в очереди с наименьшим типом меньше или равно абсолютному значениюmsgtyp
будет прочитано