- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
从send.c发送消息和进程id后,如何从get.c文件中的消息队列中获取消息?
来自 send.c:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_COUNT 200
#define BUF_SIZE 100
#define MSGSZ 255
#define KEY 10
//from http://www.tldp.org/LDP/LG/issue89/misc/raghu/send.c.txt
/*
* Declare the message structure.
*/
typedef struct msgbuf {
long mtype;
char mtext[MSGSZ + 1];
} message_buf;
static message_buf sbuf;
static size_t buf_length;
static int mqid;
int main(int argc, char*argv[])
{
pid_t pid;
int i;
char buf[BUF_SIZE];
if ((pid = getpid()) < 0) { //getting child process id
perror("unable to get pid \n");
}
else {
printf("The process id is %d \n", pid);
}
char line[256];
int c = 0; //for character count
printf("enter word/s (must be less than or equal 256 characters): \n");
fgets(line, 256, stdin);
printf("\n");
if ( c > 256 )
{
printf("Must enter less than or equal to 256 characters.");
printf("Has %d characters", countChar(line));
exit(0);
}
(void) strcpy(sbuf.mtext, line);
buf_length = strlen(sbuf.mtext) + 1;
sbuf.mtype = pid;
logMessage(sbuf.mtype, line);
}
int countChar(char *s)
{
int len = 0;
for(; *s != '\0'; s++, len++);
return len;
}
int logMessage(int serviceId,char*message)
{
int rv, mask, msgid;
key_t key = KEY;
mask = 0644|IPC_CREAT;
msgid = msgget(key, mask);
if (msgsnd(msgid, &sbuf, buf_length, IPC_NOWAIT) < 0) //sending message
{
perror("msgsnd");
exit(1);
}
else
{
printf("id - %d : message - %s \n", serviceId, message);
}
return rv;
}
来自 get.c:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <stdarg.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#define MSGSZ 255
#define MSGCHARS 255
#define KEY 10
typedef struct msgbuf
{
int mtype;
char mtext[MSGSZ];
}message_buf;
static int queue_id;
void INThandler(int);
int main(int argc, char*argv[])
{
key_t key = KEY
message_buf rbuf;
int msgflg = 0644;
int msqid = msgget(key, msgflg);
if (msqid < 0) {
perror("msgget");
exit(1);
}
rbuf.mtype = 1;
for(;;){
if (msgrcv(msqid, &rbuf, MSGSZ, 1, 0) < 0) {
perror("msgrcv");
exit(1);
}
printf("id - %d : message - %s ", rbuf.mtype, rbuf.mtext);
}
signal(SIGINT, INThandler);//the function starts with ctrl+c.
while (1)
pause();
return 0;
}
void INThandler(int sig)//this function deletes the message queue
{
signal(sig, SIG_IGN);
int mask, msgid;
key_t key = KEY;
mask = 0644;
msgid = msgget(key, mask);
if (msgid == -1) {
printf("Message queue does not exist.\n");
exit(EXIT_SUCCESS);
}
if (msgctl(msgid, IPC_RMID, NULL) == -1) {
fprintf(stderr, "Message queue could not be deleted.\n");
exit(EXIT_FAILURE);
}
else {
printf("Message queue was deleted.\n");
}
exit(0);
return EXIT_SUCCESS;
}
我能够从 send.c 成功发送进程 ID 和消息,但是在执行 get.c 时代码没有返回任何内容。你如何解决这个问题?
最佳答案
您的问题由 msgrcv()
的 POSIX 规范确定. msgtyp
参数是第四个参数,在您的代码中指定为 1
:
The argument
msgtyp
specifies the type of message requested as follows:
If
msgtyp
is 0, the first message on the queue shall be received.If
msgtyp
is greater than 0, the first message of typemsgtyp
shall be received.If
msgtyp
is less than 0, the first message of the lowest type that is less than or equal to the absolute value of msgtyp shall be received.
由于发送过程不是init
过程,因此永远不会有来自PID = 1的消息。只需将您的调用从:
if (msgrcv(msqid, &rbuf, MSGSZ, 1, 0) < 0)
到
if (msgrcv(msqid, &rbuf, MSGSZ, 0, 0) < 0)
意味着接收器的下一次运行得到:
Waiting...
id - 60464 : message - Waiting...
id - 60478 : message - Waiting...
id - 60482 : message - Waiting...
id - 71796 : message - Waiting...
其中 Waiting...
打印在 if
语句之前的循环内的 printf()
语句中。这表明来自先前失败的消息读取尝试的消息正在等待读取。
返回的消息长度为零,因为您在定义消息结构时不够仔细。特别是,接收消息结构使用 int
而不是规范要求的 long
,所以在我的机器上 sizeof(int) == 4
和 sizeof(long) == 8
并且值为小端,接收方的字符串相对于发送方的字符串错位,放置了 0 个字节。修复该问题并传输消息。
请注意,中断处理程序设置得不够早;它从未在原始代码中实际使用过。
教训:
printf()
in a signal handler .在这里会相当安全,但从技术上讲这是未定义的行为,应该避免。send.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#define MSGSZ 255
#define KEY 10
typedef struct msgbuf
{
long mtype;
char mtext[MSGSZ+1];
} message_buf;
int main(void)
{
message_buf sbuf;
sbuf.mtype = getpid();
printf("The process id is %ld\n", sbuf.mtype);
printf("enter word/s (must be less than %d characters):\n", MSGSZ+1);
if (fgets(sbuf.mtext, sizeof(sbuf.mtext), stdin) == 0)
{
printf("EOF detected\n");
exit(EXIT_FAILURE);
}
printf("\n");
key_t key = KEY;
int mask = 0644 | IPC_CREAT;
int msgid = msgget(key, mask);
if (msgid < 0)
{
fprintf(stderr, "Failed to create msg key %d\n", key);
exit(EXIT_FAILURE);
}
if (msgsnd(msgid, &sbuf, strlen(sbuf.mtext)+1, IPC_NOWAIT) < 0)
{
perror("msgsnd");
exit(EXIT_FAILURE);
}
printf("id - %ld : message - %s\n", sbuf.mtype, sbuf.mtext);
return 0;
}
recv.c
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#define MSGSZ 255
#define KEY 10
typedef struct msgbuf
{
long mtype;
char mtext[MSGSZ+1];
} message_buf;
static void INThandler(int);
int main(void)
{
key_t key = KEY;
int msgflg = 0644;
message_buf rbuf;
int msqid = msgget(key, msgflg);
if (msqid < 0)
{
perror("msgget");
exit(1);
}
signal(SIGINT, INThandler);
rbuf.mtype = 1;
for ( ; ; )
{
printf("Waiting...\n");
ssize_t nbytes = msgrcv(msqid, &rbuf, MSGSZ, 0, 0);
if (nbytes < 0)
{
perror("msgrcv");
exit(1);
}
printf("id - %ld : message (%d) - %s", rbuf.mtype, (int)nbytes, rbuf.mtext);
}
return 0;
}
static void INThandler(int sig)
{
signal(sig, SIG_IGN);
int mask, msgid;
key_t key = KEY;
mask = 0644;
msgid = msgget(key, mask);
if (msgid == -1)
{
printf("Message queue does not exist.\n");
exit(EXIT_SUCCESS);
}
if (msgctl(msgid, IPC_RMID, NULL) == -1)
{
fprintf(stderr, "Message queue could not be deleted.\n");
exit(EXIT_FAILURE);
}
else
printf("Message queue was deleted.\n");
exit(0);
}
$ ./send <<< "The message to be sent."
The process id is 71901
enter word/s (must be less than 256 characters):
id - 71901 : message - The message to be sent.
$ ./send <<< "Another message to be sent."
The process id is 71902
enter word/s (must be less than 256 characters):
id - 71902 : message - Another message to be sent.
$ ./send <<< "A third message sent to the receiver."
The process id is 71903
enter word/s (must be less than 256 characters):
id - 71903 : message - A third message sent to the receiver.
$ ./recv
Waiting...
id - 71901 : message (25) - The message to be sent.
Waiting...
id - 71902 : message (29) - Another message to be sent.
Waiting...
id - 71903 : message (39) - A third message sent to the receiver.
Waiting...
^CMessage queue was deleted.
$
关于c - 如何从一个文件获取消息和消息ID到另一个文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30437486/
我是一名优秀的程序员,十分优秀!