msgsnd 中的错误 - msgrcv,我无法查看发送的第二个字符串
error in msgsnd - msgrcv, I can't view the second string sent
嗨(抱歉我的英语不好),我正在尝试练习 Linux 在 IPC 中操作消息队列。
我创建了一个程序,允许一个进程(子进程 1)发送队列中的消息,而另一个进程(子进程 2)读取该消息。
此消息被定义为由两个字符串(str1 和 str2)和一个类型(long)组成的结构。
我想实现的目标是读取两个字符串,但结果是程序中只读取了一个。
谢谢
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <time.h>
typedef struct{
long int type;
char str1[255];
char str2[255];
}msg;
void sender(int fd_msg){
msg message;
char *string1 = "Hello";
char *string2 = "World";
strcpy(message.str1,string1);
strcpy(message.str2,string2);
message.type = 1;
if(msgsnd(fd_msg,&message,strlen(message.str1)+1,0) == -1){
printf("Error sending message at message 1 queue %d --> %s\n",errno,strerror(errno));
return;
}
message.type = 2;
if(msgsnd(fd_msg,&message,strlen(message.str2)+1,0) == -1){
printf("Error sending message at message 2 queue %d --> %s\n",errno,strerror(errno));
return;
}
if(printf("Message sent at the queue: %s -- %s\n",message.str1,message.str2) < 0){
printf("Error printing sent messages %d --> %s\n",errno,strerror(errno));
msgctl(fd_msg,IPC_RMID,NULL);
return;
}
return;
}
void receiver(int fd_msg){
msg message;
char string1[255];
char string2[255];
sleep(1);
if(msgrcv(fd_msg,&message,sizeof(message)-sizeof(long int),1,0) == -1){
printf("error reiceiving message type 1 %d --> %s\n",errno,strerror(errno));
return;
}
if(msgrcv(fd_msg,&message,sizeof(message)-sizeof(long int),2 ,0) == -1){
printf("error reiceiving message type2 %d --> %s\n",errno,strerror(errno));
return;
}
if(printf("Message reiceved! : %s -- %s\n",message.str1,message.str2) < 0){
printf("Error printing received message %d --> %s\n",errno,strerror(errno));
msgctl(fd_msg,IPC_RMID,NULL);
return;
}
strcpy(string1,message.str1);
strcpy(string2,message.str2);
//printf("string2: %s\n",messaggio.str2);
return;
}
int main(int argc, char* argv[]){
int fd_msg = -1;
int key_msg = -1;
pid_t p1;
pid_t p2;
key_msg = ftok("../Example/in.txt",55);
if((fd_msg = msgget(key_msg,IPC_CREAT | 0770)) == -1){
printf("Error creation message queue %d --> %s\n",errno, strerror(errno));
return -1;
}
if((p1 = fork()) == 0){
//child 1 (writer)
sender(fd_msg);
exit(0);
}
waitpid(p1,NULL,0);
if((p2 = fork()) == 0){
//child 2 (reader)
receiver(fd_msg);
exit(0);
}
waitpid(p2,NULL,0);
msgctl(fd_msg,IPC_RMID,NULL);
return 0;
}
您应该只发送 一条 条消息,长度为 sizeof(message)-sizeof(long int)
,就像您接收消息时所做的那样。那是因为 str1
和 str2
的 固定 长度为 255.
您只需要 一个 消息(在单个消息中发送 两个 字符串的数据)。
如您所见,您[应该]发送的“短”负载长度是 255 + 5 + 1
而 不是 5 + 1 + 5 + 1
有多种方法可以做到这一点:
- 使用完整的
sizeof(msg)
发送一条包含两个字符串的消息
- 发送一封完整大小为
str1
但长度为 str2
的消息
- 将
str1
和 str2
合并到一个缓冲区中,然后 [手动] concatenate/split 字符串
- 使用单个缓冲区并发送两条消息,每个字符串一个,仅使用每个字符串的短长度。
示例 #1:
这是使用完整消息大小的更正代码:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <time.h>
typedef struct {
long int type;
char str1[255];
char str2[255];
} msg;
void
sender(int fd_msg)
{
msg message;
char *string1 = "Hello";
char *string2 = "World";
strcpy(message.str1, string1);
strcpy(message.str2, string2);
size_t len = sizeof(message) - sizeof(long);
message.type = 1;
printf("Sending length %zu\n",len);
if (msgsnd(fd_msg, &message, len, 0) == -1) {
printf("Error sending message at message 1 queue %d --> %s\n", errno, strerror(errno));
return;
}
if (printf("Message sent at the queue: %s -- %s\n", message.str1, message.str2) < 0) {
printf("Error printing sent messages %d --> %s\n", errno, strerror(errno));
msgctl(fd_msg, IPC_RMID, NULL);
return;
}
return;
}
void
receiver(int fd_msg)
{
msg message;
char string1[255];
char string2[255];
sleep(1);
ssize_t len = msgrcv(fd_msg, &message, sizeof(message) - sizeof(long int), 1, 0);
if (len == -1) {
printf("error receiving message type 1 %d --> %s\n", errno, strerror(errno));
return;
}
printf("Received length: %zu\n",len);
if (printf("Message received! : %s -- %s\n", message.str1, message.str2) < 0) {
printf("Error printing received message %d --> %s\n", errno, strerror(errno));
msgctl(fd_msg, IPC_RMID, NULL);
return;
}
strcpy(string1, message.str1);
strcpy(string2, message.str2);
// printf("string2: %s\n",messaggio.str2);
return;
}
int
main(int argc, char *argv[])
{
int fd_msg = -1;
int key_msg = -1;
pid_t p1;
pid_t p2;
key_msg = ftok("../Example/in.txt", 55);
if ((fd_msg = msgget(key_msg, IPC_CREAT | 0770)) == -1) {
printf("Error creation message queue %d --> %s\n", errno, strerror(errno));
return -1;
}
if ((p1 = fork()) == 0) {
// child 1 (writer)
sender(fd_msg);
exit(0);
}
waitpid(p1, NULL, 0);
if ((p2 = fork()) == 0) {
// child 2 (reader)
receiver(fd_msg);
exit(0);
}
waitpid(p2, NULL, 0);
msgctl(fd_msg, IPC_RMID, NULL);
return 0;
}
程序输出如下:
Sending length 512
Message sent at the queue: Hello -- World
Received length: 512
Message received! : Hello -- World
示例 #2:
这是 str2
使用“短”长度的程序:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <time.h>
typedef struct {
long int type;
char str1[255];
char str2[255];
} msg;
void
sender(int fd_msg)
{
msg message;
char *string1 = "Hello";
char *string2 = "World";
strcpy(message.str1, string1);
strcpy(message.str2, string2);
size_t len = sizeof(message.str1) + strlen(message.str2) + 1;
message.type = 1;
printf("Sending length %zu\n",len);
if (msgsnd(fd_msg, &message, len, 0) == -1) {
printf("Error sending message at message 1 queue %d --> %s\n", errno, strerror(errno));
return;
}
if (printf("Message sent at the queue: %s -- %s\n", message.str1, message.str2) < 0) {
printf("Error printing sent messages %d --> %s\n", errno, strerror(errno));
msgctl(fd_msg, IPC_RMID, NULL);
return;
}
return;
}
void
receiver(int fd_msg)
{
msg message;
char string1[255];
char string2[255];
sleep(1);
ssize_t len = msgrcv(fd_msg, &message, sizeof(message) - sizeof(long int), 1, 0);
if (len == -1) {
printf("error receiving message type 1 %d --> %s\n", errno, strerror(errno));
return;
}
printf("Received length: %zu\n",len);
if (printf("Message received! : %s -- %s\n", message.str1, message.str2) < 0) {
printf("Error printing received message %d --> %s\n", errno, strerror(errno));
msgctl(fd_msg, IPC_RMID, NULL);
return;
}
strcpy(string1, message.str1);
strcpy(string2, message.str2);
// printf("string2: %s\n",messaggio.str2);
return;
}
int
main(int argc, char *argv[])
{
int fd_msg = -1;
int key_msg = -1;
pid_t p1;
pid_t p2;
key_msg = ftok("../Example/in.txt", 55);
if ((fd_msg = msgget(key_msg, IPC_CREAT | 0770)) == -1) {
printf("Error creation message queue %d --> %s\n", errno, strerror(errno));
return -1;
}
if ((p1 = fork()) == 0) {
// child 1 (writer)
sender(fd_msg);
exit(0);
}
waitpid(p1, NULL, 0);
if ((p2 = fork()) == 0) {
// child 2 (reader)
receiver(fd_msg);
exit(0);
}
waitpid(p2, NULL, 0);
msgctl(fd_msg, IPC_RMID, NULL);
return 0;
}
程序输出如下:
Sending length 261
Message sent at the queue: Hello -- World
Received length: 261
Message received! : Hello -- World
示例 #3:
使用 separate str1
和 str2
强制我们发送 str1
的完整大小,即使实际字符串长度更短。
要发送一条 单个 消息,该消息具有 两个 字符串并发送 仅 我们的长度需要将 str1
和 str2
组合成一个 单个 缓冲区(例如 strs
)。这需要我们将两个字符串连接到缓冲区中。
这还要求接收方恢复两个单独的字符串。
代码如下:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <time.h>
typedef struct {
long int type;
char strs[512];
} msg;
void
sender(int fd_msg)
{
msg message;
char *string1 = "Hello";
char *string2 = "World";
char *cp = message.strs;
strcpy(cp, string1);
cp += strlen(cp) + 1;
strcpy(cp, string2);
cp += strlen(cp) + 1;
size_t len = cp - message.strs;
message.type = 1;
printf("Sending length %zu\n",len);
if (msgsnd(fd_msg, &message, len, 0) == -1) {
printf("Error sending message at message 1 queue %d --> %s\n", errno, strerror(errno));
return;
}
}
void
receiver(int fd_msg)
{
msg message;
char string1[255];
char string2[255];
sleep(1);
ssize_t len = msgrcv(fd_msg, &message, sizeof(message) - sizeof(long int), 1, 0);
if (len == -1) {
printf("error receiving message type 1 %d --> %s\n", errno, strerror(errno));
return;
}
printf("Received length: %zu\n",len);
char *cp = message.strs;
strcpy(string1, cp);
cp += strlen(cp) + 1;
strcpy(string2, cp);
cp += strlen(cp) + 1;
printf("string1: %s\n",string1);
printf("string2: %s\n",string2);
return;
}
int
main(int argc, char *argv[])
{
int fd_msg = -1;
int key_msg = -1;
pid_t p1;
pid_t p2;
key_msg = ftok("../Example/in.txt", 55);
if ((fd_msg = msgget(key_msg, IPC_CREAT | 0770)) == -1) {
printf("Error creation message queue %d --> %s\n", errno, strerror(errno));
return -1;
}
if ((p1 = fork()) == 0) {
// child 1 (writer)
sender(fd_msg);
exit(0);
}
waitpid(p1, NULL, 0);
if ((p2 = fork()) == 0) {
// child 2 (reader)
receiver(fd_msg);
exit(0);
}
waitpid(p2, NULL, 0);
msgctl(fd_msg, IPC_RMID, NULL);
return 0;
}
程序输出如下:
Sending length 12
Received length: 12
string1: Hello
string2: World
示例 #4:
我可能会执行示例 #1 并发送完整的结构长度。
或者,我将使用示例 #3 中的组合缓冲区,但会发送 两条 条单独的消息,每个字符串一条消息:
代码如下:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <time.h>
typedef struct {
long int type;
char str[255];
} msg;
void
sendone(int fd_msg,int type,const char *str)
{
msg message;
strcpy(message.str, str);
size_t len = strlen(str) + 1;
message.type = type;
printf("Sending type %ld length %zu\n",message.type,len);
if (msgsnd(fd_msg, &message, len, 0) == -1) {
printf("Error sending message at message 1 queue %d --> %s\n", errno, strerror(errno));
return;
}
printf("Message sent at the queue: %s\n", message.str);
}
void
sender(int fd_msg)
{
char *string1 = "Hello";
char *string2 = "World";
sendone(fd_msg,2,string2);
sendone(fd_msg,1,string1);
return;
}
ssize_t
recvone(int fd_msg,msg *message)
{
int type = 0;
ssize_t len = msgrcv(fd_msg, message, sizeof(msg) - sizeof(long int), type, 0);
if (len == -1) {
printf("error receiving message %d --> %s\n", errno, strerror(errno));
return len;
}
printf("Received type %ld message of length: %zu\n",message->type,len);
printf("Message received! : %s\n",message->str);
return len;
}
void
receiver(int fd_msg)
{
msg message;
char strings[2][255];
sleep(1);
// deliberately receive messages in any order
for (int imsg = 1; imsg <= 2; ++imsg) {
recvone(fd_msg,&message);
strcpy(strings[message.type - 1],message.str);
}
for (int imsg = 1; imsg <= 2; ++imsg)
printf("receiver: string %d: %s\n",imsg,strings[imsg - 1]);
return;
}
int
main(int argc, char *argv[])
{
int fd_msg = -1;
int key_msg = -1;
pid_t p1;
pid_t p2;
key_msg = ftok("../Example/in.txt", 55);
if ((fd_msg = msgget(key_msg, IPC_CREAT | 0770)) == -1) {
printf("Error creation message queue %d --> %s\n", errno, strerror(errno));
return -1;
}
if ((p1 = fork()) == 0) {
// child 1 (writer)
sender(fd_msg);
exit(0);
}
waitpid(p1, NULL, 0);
if ((p2 = fork()) == 0) {
// child 2 (reader)
receiver(fd_msg);
exit(0);
}
waitpid(p2, NULL, 0);
msgctl(fd_msg, IPC_RMID, NULL);
return 0;
}
程序输出如下:
Sending type 2 length 6
Message sent at the queue: World
Sending type 1 length 6
Message sent at the queue: Hello
Received type 2 message of length: 6
Message received! : World
Received type 1 message of length: 6
Message received! : Hello
receiver: string 1: Hello
receiver: string 2: World
嗨(抱歉我的英语不好),我正在尝试练习 Linux 在 IPC 中操作消息队列。 我创建了一个程序,允许一个进程(子进程 1)发送队列中的消息,而另一个进程(子进程 2)读取该消息。 此消息被定义为由两个字符串(str1 和 str2)和一个类型(long)组成的结构。 我想实现的目标是读取两个字符串,但结果是程序中只读取了一个。 谢谢
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <time.h>
typedef struct{
long int type;
char str1[255];
char str2[255];
}msg;
void sender(int fd_msg){
msg message;
char *string1 = "Hello";
char *string2 = "World";
strcpy(message.str1,string1);
strcpy(message.str2,string2);
message.type = 1;
if(msgsnd(fd_msg,&message,strlen(message.str1)+1,0) == -1){
printf("Error sending message at message 1 queue %d --> %s\n",errno,strerror(errno));
return;
}
message.type = 2;
if(msgsnd(fd_msg,&message,strlen(message.str2)+1,0) == -1){
printf("Error sending message at message 2 queue %d --> %s\n",errno,strerror(errno));
return;
}
if(printf("Message sent at the queue: %s -- %s\n",message.str1,message.str2) < 0){
printf("Error printing sent messages %d --> %s\n",errno,strerror(errno));
msgctl(fd_msg,IPC_RMID,NULL);
return;
}
return;
}
void receiver(int fd_msg){
msg message;
char string1[255];
char string2[255];
sleep(1);
if(msgrcv(fd_msg,&message,sizeof(message)-sizeof(long int),1,0) == -1){
printf("error reiceiving message type 1 %d --> %s\n",errno,strerror(errno));
return;
}
if(msgrcv(fd_msg,&message,sizeof(message)-sizeof(long int),2 ,0) == -1){
printf("error reiceiving message type2 %d --> %s\n",errno,strerror(errno));
return;
}
if(printf("Message reiceved! : %s -- %s\n",message.str1,message.str2) < 0){
printf("Error printing received message %d --> %s\n",errno,strerror(errno));
msgctl(fd_msg,IPC_RMID,NULL);
return;
}
strcpy(string1,message.str1);
strcpy(string2,message.str2);
//printf("string2: %s\n",messaggio.str2);
return;
}
int main(int argc, char* argv[]){
int fd_msg = -1;
int key_msg = -1;
pid_t p1;
pid_t p2;
key_msg = ftok("../Example/in.txt",55);
if((fd_msg = msgget(key_msg,IPC_CREAT | 0770)) == -1){
printf("Error creation message queue %d --> %s\n",errno, strerror(errno));
return -1;
}
if((p1 = fork()) == 0){
//child 1 (writer)
sender(fd_msg);
exit(0);
}
waitpid(p1,NULL,0);
if((p2 = fork()) == 0){
//child 2 (reader)
receiver(fd_msg);
exit(0);
}
waitpid(p2,NULL,0);
msgctl(fd_msg,IPC_RMID,NULL);
return 0;
}
您应该只发送 一条 条消息,长度为 sizeof(message)-sizeof(long int)
,就像您接收消息时所做的那样。那是因为 str1
和 str2
的 固定 长度为 255.
您只需要 一个 消息(在单个消息中发送 两个 字符串的数据)。
如您所见,您[应该]发送的“短”负载长度是 255 + 5 + 1
而 不是 5 + 1 + 5 + 1
有多种方法可以做到这一点:
- 使用完整的
sizeof(msg)
发送一条包含两个字符串的消息
- 发送一封完整大小为
str1
但长度为str2
的消息
- 将
str1
和str2
合并到一个缓冲区中,然后 [手动] concatenate/split 字符串 - 使用单个缓冲区并发送两条消息,每个字符串一个,仅使用每个字符串的短长度。
示例 #1:
这是使用完整消息大小的更正代码:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <time.h>
typedef struct {
long int type;
char str1[255];
char str2[255];
} msg;
void
sender(int fd_msg)
{
msg message;
char *string1 = "Hello";
char *string2 = "World";
strcpy(message.str1, string1);
strcpy(message.str2, string2);
size_t len = sizeof(message) - sizeof(long);
message.type = 1;
printf("Sending length %zu\n",len);
if (msgsnd(fd_msg, &message, len, 0) == -1) {
printf("Error sending message at message 1 queue %d --> %s\n", errno, strerror(errno));
return;
}
if (printf("Message sent at the queue: %s -- %s\n", message.str1, message.str2) < 0) {
printf("Error printing sent messages %d --> %s\n", errno, strerror(errno));
msgctl(fd_msg, IPC_RMID, NULL);
return;
}
return;
}
void
receiver(int fd_msg)
{
msg message;
char string1[255];
char string2[255];
sleep(1);
ssize_t len = msgrcv(fd_msg, &message, sizeof(message) - sizeof(long int), 1, 0);
if (len == -1) {
printf("error receiving message type 1 %d --> %s\n", errno, strerror(errno));
return;
}
printf("Received length: %zu\n",len);
if (printf("Message received! : %s -- %s\n", message.str1, message.str2) < 0) {
printf("Error printing received message %d --> %s\n", errno, strerror(errno));
msgctl(fd_msg, IPC_RMID, NULL);
return;
}
strcpy(string1, message.str1);
strcpy(string2, message.str2);
// printf("string2: %s\n",messaggio.str2);
return;
}
int
main(int argc, char *argv[])
{
int fd_msg = -1;
int key_msg = -1;
pid_t p1;
pid_t p2;
key_msg = ftok("../Example/in.txt", 55);
if ((fd_msg = msgget(key_msg, IPC_CREAT | 0770)) == -1) {
printf("Error creation message queue %d --> %s\n", errno, strerror(errno));
return -1;
}
if ((p1 = fork()) == 0) {
// child 1 (writer)
sender(fd_msg);
exit(0);
}
waitpid(p1, NULL, 0);
if ((p2 = fork()) == 0) {
// child 2 (reader)
receiver(fd_msg);
exit(0);
}
waitpid(p2, NULL, 0);
msgctl(fd_msg, IPC_RMID, NULL);
return 0;
}
程序输出如下:
Sending length 512
Message sent at the queue: Hello -- World
Received length: 512
Message received! : Hello -- World
示例 #2:
这是 str2
使用“短”长度的程序:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <time.h>
typedef struct {
long int type;
char str1[255];
char str2[255];
} msg;
void
sender(int fd_msg)
{
msg message;
char *string1 = "Hello";
char *string2 = "World";
strcpy(message.str1, string1);
strcpy(message.str2, string2);
size_t len = sizeof(message.str1) + strlen(message.str2) + 1;
message.type = 1;
printf("Sending length %zu\n",len);
if (msgsnd(fd_msg, &message, len, 0) == -1) {
printf("Error sending message at message 1 queue %d --> %s\n", errno, strerror(errno));
return;
}
if (printf("Message sent at the queue: %s -- %s\n", message.str1, message.str2) < 0) {
printf("Error printing sent messages %d --> %s\n", errno, strerror(errno));
msgctl(fd_msg, IPC_RMID, NULL);
return;
}
return;
}
void
receiver(int fd_msg)
{
msg message;
char string1[255];
char string2[255];
sleep(1);
ssize_t len = msgrcv(fd_msg, &message, sizeof(message) - sizeof(long int), 1, 0);
if (len == -1) {
printf("error receiving message type 1 %d --> %s\n", errno, strerror(errno));
return;
}
printf("Received length: %zu\n",len);
if (printf("Message received! : %s -- %s\n", message.str1, message.str2) < 0) {
printf("Error printing received message %d --> %s\n", errno, strerror(errno));
msgctl(fd_msg, IPC_RMID, NULL);
return;
}
strcpy(string1, message.str1);
strcpy(string2, message.str2);
// printf("string2: %s\n",messaggio.str2);
return;
}
int
main(int argc, char *argv[])
{
int fd_msg = -1;
int key_msg = -1;
pid_t p1;
pid_t p2;
key_msg = ftok("../Example/in.txt", 55);
if ((fd_msg = msgget(key_msg, IPC_CREAT | 0770)) == -1) {
printf("Error creation message queue %d --> %s\n", errno, strerror(errno));
return -1;
}
if ((p1 = fork()) == 0) {
// child 1 (writer)
sender(fd_msg);
exit(0);
}
waitpid(p1, NULL, 0);
if ((p2 = fork()) == 0) {
// child 2 (reader)
receiver(fd_msg);
exit(0);
}
waitpid(p2, NULL, 0);
msgctl(fd_msg, IPC_RMID, NULL);
return 0;
}
程序输出如下:
Sending length 261
Message sent at the queue: Hello -- World
Received length: 261
Message received! : Hello -- World
示例 #3:
使用 separate str1
和 str2
强制我们发送 str1
的完整大小,即使实际字符串长度更短。
要发送一条 单个 消息,该消息具有 两个 字符串并发送 仅 我们的长度需要将 str1
和 str2
组合成一个 单个 缓冲区(例如 strs
)。这需要我们将两个字符串连接到缓冲区中。
这还要求接收方恢复两个单独的字符串。
代码如下:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <time.h>
typedef struct {
long int type;
char strs[512];
} msg;
void
sender(int fd_msg)
{
msg message;
char *string1 = "Hello";
char *string2 = "World";
char *cp = message.strs;
strcpy(cp, string1);
cp += strlen(cp) + 1;
strcpy(cp, string2);
cp += strlen(cp) + 1;
size_t len = cp - message.strs;
message.type = 1;
printf("Sending length %zu\n",len);
if (msgsnd(fd_msg, &message, len, 0) == -1) {
printf("Error sending message at message 1 queue %d --> %s\n", errno, strerror(errno));
return;
}
}
void
receiver(int fd_msg)
{
msg message;
char string1[255];
char string2[255];
sleep(1);
ssize_t len = msgrcv(fd_msg, &message, sizeof(message) - sizeof(long int), 1, 0);
if (len == -1) {
printf("error receiving message type 1 %d --> %s\n", errno, strerror(errno));
return;
}
printf("Received length: %zu\n",len);
char *cp = message.strs;
strcpy(string1, cp);
cp += strlen(cp) + 1;
strcpy(string2, cp);
cp += strlen(cp) + 1;
printf("string1: %s\n",string1);
printf("string2: %s\n",string2);
return;
}
int
main(int argc, char *argv[])
{
int fd_msg = -1;
int key_msg = -1;
pid_t p1;
pid_t p2;
key_msg = ftok("../Example/in.txt", 55);
if ((fd_msg = msgget(key_msg, IPC_CREAT | 0770)) == -1) {
printf("Error creation message queue %d --> %s\n", errno, strerror(errno));
return -1;
}
if ((p1 = fork()) == 0) {
// child 1 (writer)
sender(fd_msg);
exit(0);
}
waitpid(p1, NULL, 0);
if ((p2 = fork()) == 0) {
// child 2 (reader)
receiver(fd_msg);
exit(0);
}
waitpid(p2, NULL, 0);
msgctl(fd_msg, IPC_RMID, NULL);
return 0;
}
程序输出如下:
Sending length 12
Received length: 12
string1: Hello
string2: World
示例 #4:
我可能会执行示例 #1 并发送完整的结构长度。
或者,我将使用示例 #3 中的组合缓冲区,但会发送 两条 条单独的消息,每个字符串一条消息:
代码如下:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <time.h>
typedef struct {
long int type;
char str[255];
} msg;
void
sendone(int fd_msg,int type,const char *str)
{
msg message;
strcpy(message.str, str);
size_t len = strlen(str) + 1;
message.type = type;
printf("Sending type %ld length %zu\n",message.type,len);
if (msgsnd(fd_msg, &message, len, 0) == -1) {
printf("Error sending message at message 1 queue %d --> %s\n", errno, strerror(errno));
return;
}
printf("Message sent at the queue: %s\n", message.str);
}
void
sender(int fd_msg)
{
char *string1 = "Hello";
char *string2 = "World";
sendone(fd_msg,2,string2);
sendone(fd_msg,1,string1);
return;
}
ssize_t
recvone(int fd_msg,msg *message)
{
int type = 0;
ssize_t len = msgrcv(fd_msg, message, sizeof(msg) - sizeof(long int), type, 0);
if (len == -1) {
printf("error receiving message %d --> %s\n", errno, strerror(errno));
return len;
}
printf("Received type %ld message of length: %zu\n",message->type,len);
printf("Message received! : %s\n",message->str);
return len;
}
void
receiver(int fd_msg)
{
msg message;
char strings[2][255];
sleep(1);
// deliberately receive messages in any order
for (int imsg = 1; imsg <= 2; ++imsg) {
recvone(fd_msg,&message);
strcpy(strings[message.type - 1],message.str);
}
for (int imsg = 1; imsg <= 2; ++imsg)
printf("receiver: string %d: %s\n",imsg,strings[imsg - 1]);
return;
}
int
main(int argc, char *argv[])
{
int fd_msg = -1;
int key_msg = -1;
pid_t p1;
pid_t p2;
key_msg = ftok("../Example/in.txt", 55);
if ((fd_msg = msgget(key_msg, IPC_CREAT | 0770)) == -1) {
printf("Error creation message queue %d --> %s\n", errno, strerror(errno));
return -1;
}
if ((p1 = fork()) == 0) {
// child 1 (writer)
sender(fd_msg);
exit(0);
}
waitpid(p1, NULL, 0);
if ((p2 = fork()) == 0) {
// child 2 (reader)
receiver(fd_msg);
exit(0);
}
waitpid(p2, NULL, 0);
msgctl(fd_msg, IPC_RMID, NULL);
return 0;
}
程序输出如下:
Sending type 2 length 6
Message sent at the queue: World
Sending type 1 length 6
Message sent at the queue: Hello
Received type 2 message of length: 6
Message received! : World
Received type 1 message of length: 6
Message received! : Hello
receiver: string 1: Hello
receiver: string 2: World