消息队列(msgget - msgsnd - msgrcv)Linux - EIDRM
Message queue (msgget - msgsnd - msgrcv) Linux - EIDRM
这是我的问题:
我正在尝试在服务器和客户端之间实现消息队列。
为此,我有两个文件,msq-server.c
和 msq-client.c
.
我使用函数 msgctl(msqid, IPC_RMID, &buf)
退出服务器(当我们要求他读取消息队列 3 次,每秒一次,例如)。
和往常一样,msqid
由msgget函数设置,buf由struct msqid_ds buf
定义。
官方 msgctl 文档说 reader(客户端)的 errno 设置为 EIDRM (43),我想在它发生时显示自定义错误。但是当我尝试从关闭的服务器读取消息时,函数
msgrcv(msqid, &message, 64, 0, IPC_NOWAIT)
returns EINVAL 错误。我假设 msqid 是有罪的
对于函数 msgget
- 在服务器上:我使用
IPC_CREAT | IPC_EXCL |0666
标志
- 在客户端:我使用
IPC_EXCL | 0666
标志
感谢您的帮助
msgrcv() 将 return EIDRM (43) 当您在通过 msgctl() 删除队列时读取消息队列。
msgrcv() 将 return EINVAL (22) 当您尝试从不再存在的消息队列中读取时(因为您已经删除了它)。
参见下面的示例。
服务器已启动并将一条消息放入队列。然后等待。
客户端启动并读取第一条消息,然后阻塞等待从未到达的第二条消息。
服务器在客户端等待第二条消息时移除队列,并且看到了 EIDRM return 代码。
然后客户端尝试再次读取,因为没有队列可用,所以看到了 EINVAL。
msg_server.c
#include <sys/msg.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct msgbuf {
long mType;
char mText[50];
};
int main() {
char txtBuf[50];
int qId;
key_t key;
struct msgbuf msg, buf;
struct msqid_ds msgCtlBuf;
if ( ( key = ftok( "/tmp", 'C' ) ) == -1 ) {
perror( "server: ftok failed:" );
exit( 1 );
}
printf( "server: System V IPC key = %u\n", key );
if ( ( qId = msgget( key, IPC_CREAT | 0666 ) ) == -1 ) {
perror( "server: Failed to create message queue:" );
exit( 2 );
}
printf( "server: Message queue id = %u\n", qId );
strcpy( msg.mText, "This is a message" );
msg.mType = 1;
if ( msgsnd( qId, &msg, sizeof msg.mText, 0 ) == -1 ) {
perror( "server: msgsnd failed:" );
exit( 3 );
}
printf( "server: Message sent successfully\n" );
printf( "server: waiting..." );
sleep( 15 );
printf( "server: done waiting. removing message queue...\n" );
if ( msgctl( qId, IPC_RMID, &msgCtlBuf ) == -1 ) {
perror( "server: msgctl failed:" );
exit( 4 );
}
printf( "server: Message queue removed OK\n" );
}
msg_client.c
#include <sys/msg.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
struct msgbuf {
long mType;
char mText[50];
};
int main() {
char txtBuf[50];
int qId;
key_t key;
struct msgbuf msg, buf;
struct msqid_ds msgCtlBuf;
if ( ( key = ftok( "/tmp", 'C' ) ) == -1 ) {
perror( "client: ftok failed:" );
exit( 1 );
}
printf( "client: System V IPC key = %u\n", key );
if ( ( qId = msgget( key, IPC_CREAT | 0666 ) ) == -1 ) {
perror( "client: Failed to create message queue:" );
exit( 2 );
}
printf( "client: Message queue id = %u\n", qId );
if ( msgrcv( qId, &buf, sizeof msg.mText, 1, 0 ) == -1 )
perror( "client: msgrcv failed:" );
else
printf( "client: Message received = %s\n", buf.mText );
//
// attempt read again and block on queue waiting for server to IPC_RMID
//
if ( msgrcv( qId, &buf, sizeof msg.mText, 1, 0 ) == -1 )
perror( "client: msgrcv failed:" );
else
printf( "client: Message received = %s\n", buf.mText );
printf( "client: errno = %d\n", errno );
//
// attempt read again but message queue should now be gone
//
if ( msgrcv( qId, &buf, sizeof msg.mText, 1, 0 ) == -1 )
perror( "client: msgrcv failed:" );
else
printf( "client: Message received = %s\n", buf.mText );
printf( "client: errno = %d\n", errno );
}
./msg_server &
[1] 668
服务器:系统 V IPC 密钥 = 1124335618
服务器:消息队列 id = 262144
服务器:消息发送成功
./msg_client
客户端:系统 V IPC 密钥 = 1124335618
客户端:消息队列 id = 262144
客户端:收到消息=这是一条消息
服务器:等待...服务器:等待完成。删除消息队列...
服务器:消息队列已删除正常
客户端:msgrcv 失败:: 标识符已删除
客户端:errno = 43
客户端:msgrcv 失败::参数无效
客户端:errno = 22
[1]+ 退出 33 ./msg_server
这是我的问题:
我正在尝试在服务器和客户端之间实现消息队列。
为此,我有两个文件,msq-server.c
和 msq-client.c
.
我使用函数 msgctl(msqid, IPC_RMID, &buf)
退出服务器(当我们要求他读取消息队列 3 次,每秒一次,例如)。
和往常一样,msqid
由msgget函数设置,buf由struct msqid_ds buf
定义。
官方 msgctl 文档说 reader(客户端)的 errno 设置为 EIDRM (43),我想在它发生时显示自定义错误。但是当我尝试从关闭的服务器读取消息时,函数
msgrcv(msqid, &message, 64, 0, IPC_NOWAIT)
returns EINVAL 错误。我假设 msqid 是有罪的
对于函数 msgget
- 在服务器上:我使用
IPC_CREAT | IPC_EXCL |0666
标志 - 在客户端:我使用
IPC_EXCL | 0666
标志
感谢您的帮助
msgrcv() 将 return EIDRM (43) 当您在通过 msgctl() 删除队列时读取消息队列。
msgrcv() 将 return EINVAL (22) 当您尝试从不再存在的消息队列中读取时(因为您已经删除了它)。
参见下面的示例。
服务器已启动并将一条消息放入队列。然后等待。
客户端启动并读取第一条消息,然后阻塞等待从未到达的第二条消息。
服务器在客户端等待第二条消息时移除队列,并且看到了 EIDRM return 代码。
然后客户端尝试再次读取,因为没有队列可用,所以看到了 EINVAL。
msg_server.c
#include <sys/msg.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct msgbuf {
long mType;
char mText[50];
};
int main() {
char txtBuf[50];
int qId;
key_t key;
struct msgbuf msg, buf;
struct msqid_ds msgCtlBuf;
if ( ( key = ftok( "/tmp", 'C' ) ) == -1 ) {
perror( "server: ftok failed:" );
exit( 1 );
}
printf( "server: System V IPC key = %u\n", key );
if ( ( qId = msgget( key, IPC_CREAT | 0666 ) ) == -1 ) {
perror( "server: Failed to create message queue:" );
exit( 2 );
}
printf( "server: Message queue id = %u\n", qId );
strcpy( msg.mText, "This is a message" );
msg.mType = 1;
if ( msgsnd( qId, &msg, sizeof msg.mText, 0 ) == -1 ) {
perror( "server: msgsnd failed:" );
exit( 3 );
}
printf( "server: Message sent successfully\n" );
printf( "server: waiting..." );
sleep( 15 );
printf( "server: done waiting. removing message queue...\n" );
if ( msgctl( qId, IPC_RMID, &msgCtlBuf ) == -1 ) {
perror( "server: msgctl failed:" );
exit( 4 );
}
printf( "server: Message queue removed OK\n" );
}
msg_client.c
#include <sys/msg.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
struct msgbuf {
long mType;
char mText[50];
};
int main() {
char txtBuf[50];
int qId;
key_t key;
struct msgbuf msg, buf;
struct msqid_ds msgCtlBuf;
if ( ( key = ftok( "/tmp", 'C' ) ) == -1 ) {
perror( "client: ftok failed:" );
exit( 1 );
}
printf( "client: System V IPC key = %u\n", key );
if ( ( qId = msgget( key, IPC_CREAT | 0666 ) ) == -1 ) {
perror( "client: Failed to create message queue:" );
exit( 2 );
}
printf( "client: Message queue id = %u\n", qId );
if ( msgrcv( qId, &buf, sizeof msg.mText, 1, 0 ) == -1 )
perror( "client: msgrcv failed:" );
else
printf( "client: Message received = %s\n", buf.mText );
//
// attempt read again and block on queue waiting for server to IPC_RMID
//
if ( msgrcv( qId, &buf, sizeof msg.mText, 1, 0 ) == -1 )
perror( "client: msgrcv failed:" );
else
printf( "client: Message received = %s\n", buf.mText );
printf( "client: errno = %d\n", errno );
//
// attempt read again but message queue should now be gone
//
if ( msgrcv( qId, &buf, sizeof msg.mText, 1, 0 ) == -1 )
perror( "client: msgrcv failed:" );
else
printf( "client: Message received = %s\n", buf.mText );
printf( "client: errno = %d\n", errno );
}
./msg_server &
[1] 668
服务器:系统 V IPC 密钥 = 1124335618
服务器:消息队列 id = 262144
服务器:消息发送成功
./msg_client
客户端:系统 V IPC 密钥 = 1124335618
客户端:消息队列 id = 262144
客户端:收到消息=这是一条消息
服务器:等待...服务器:等待完成。删除消息队列...
服务器:消息队列已删除正常
客户端:msgrcv 失败:: 标识符已删除
客户端:errno = 43
客户端:msgrcv 失败::参数无效
客户端:errno = 22
[1]+ 退出 33 ./msg_server