您似乎正在尝试执行进程间通信(IPC)。没有与读/写进行1对1通信同步,父级或子级可以一次向文件描述符写入任意多的内容,并且由于它们是异步运行的,因此您必须确保已准备好处理此问题。
通常,这是通过发送一个标头来完成的,该标头包含固定大小的每条消息,其中包含有效负载的长度。例如:
协议标头
#include <stdint.h>
struct Message
{
uint8_t length; // assuming a maximum message length of 255 bytes, adjust as needed.
};
您可以在这里定义额外的内容,通常最好包括版本,可能是序列ID等。如果您通过网络进行通信,则此标头的大小在所有硬件实现中都是绝对的,因此需要使用stdint定义来确保架构之间的兼容性,这一点很重要。如果跨架构工作,确保endian是一致的也是一个好主意。
发送消息
const char data[] = "example";
// create a buffer large enough to pack the header and data into it
const uint8_t len = strlen(data) + 1;
char buffer[sizeof(struct Message) + len];
// populate the header
struct Message *m = (struct Message *)buffer;
m->length = len;
// copy in the payload after the header
memcpy(buffer + sizeof(struct Message), data, len);
// write the packed buffer
write(fd, buffer, sizeof(struct Message) + len);
阅读消息
struct Message m;
if (read(fd, &m, sizeof(struct Message)) != sizeof(struct Message))
{
fprintf(stderr, "Failed to read the header\n");
exit(1);
}
// If required perform validation on the header here
ssize_t offset = 0;
char data[m.length];
while(offset < m.length)
{
ssize_t r = read(fd, data + offset, m.length - offset);
if (r < 0)
{
fprintf(stderr, "Read of message body failed\n");
exit(1);
}
if (r == 0)
{
fprintf(stderr, "The sender closed the connection\n");
exit(1);
}
offset += r;
}
printf("Message Length: %u, Message Data: %s\n", m.length, data);
需要执行while循环读取,因为如果发送方超出了写入缓冲区,并且正在阻塞等待写入剩余数据,则数据可能已被分割成块。标题也可以分为多个块,理想情况下也应该使用相同的技术读取,但为了简洁起见,我省略了这一点。