他の回答の多くは、データに何らかのプロトコルを使用することに言及しており、これが正しいアプローチであると私は信じています。このプロトコルは、必要に応じて単純または複雑にすることができます。私はあなたが役に立つと思うかもしれないいくつかの例を提供しました1。
単純なケースでは、長さバイトの後にデータバイト(つまりC文字列)が続く場合があります。
+ -------------- +
| 長さバイト|
+ -------------- +
| データバイト|
+ -------------- +
ライター:
uint8_t foo[UCHAR_MAX+1];
uint8_t len;
int fd;
mkfifo("/tmp/myfifo", 0660);
fd = open("/tmp/myfifo", O_WRONLY);
memset(foo, UCHAR_MAX+1, 0);
len = (uint8_t)snprintf((char *)foo, UCHAR_MAX, "Hello World!");
/* The length byte is written first followed by the data. */
write(fd, len, 1);
write(fd, foo, strlen(foo));
読者:
uint8_t buf[UCHAR_MAX+1];
uint8_t len;
int fd;
fd = open("/tmp/myfifo", O_RDONLY);
memset(buf, UCHAR_MAX+1, 0);
/* The length byte is read first followed by a read
* for the specified number of data bytes.
*/
read(fd, len, 1);
read(fd, buf, len);
より複雑なケースでは、長さバイトの後に、単純なC文字列以上を含むデータバイトが続く場合があります。
+ ---------------- +
| 長さバイト|
+ ---------------- +
| データ型バイト|
+ ---------------- +
| データバイト|
+ ---------------- +
共通ヘッダー:
#define FOO_TYPE 100
#define BAR_TYPE 200
typedef struct {
uint8_t type;
uint32_t flags;
int8_t msg[20];
} __attribute__((aligned, packed)) foo_t;
typedef struct {
uint8_t type;
uint16_t flags;
int32_t value;
} __attribute__((aligned, packed)) bar_t;
ライター:
foo_t foo;
unsigned char len;
int fd;
mkfifo("/tmp/myfifo", 0660);
fd = open("/tmp/myfifo", O_WRONLY);
memset(&foo, sizeof(foo), 0);
foo.type = FOO_TYPE;
foo.flags = 0xDEADBEEF;
snprintf(foo.msg, 20-1, "Hello World!");
/* The length byte is written first followed by the data. */
len = sizeof(foo);
write(fd, len, 1);
write(fd, foo, sizeof(foo));
読者:
uint8_t buf[UCHAR_MAX+1];
uint8_t len;
uint16_t type;
union data {
foo_t * foo;
bar_t * bar;
}
int fd;
fd = open("/tmp/myfifo", O_RDONLY);
memset(buf, UCHAR_MAX+1, 0);
/* The length byte is read first followed by a read
* for the specified number of data bytes.
*/
read(fd, len, 1);
read(fd, buf, len);
/* Retrieve the message type from the beginning of the buffer. */
memcpy(&type, buf, sizeof(type));
/* Process the data depending on the type. */
switch(type) {
case FOO_TYPE:
data.foo = (foo_t)buf;
printf("0x%08X: %s\n", data.foo.flags, data.foo.msg);
break;
case BAR_TYPE:
data.bar = (bar_t)buf;
printf("0x%04X: %d\n", data.bar.flags, data.bar.value);
break;
default:
printf("unrecognized type\n");
}
1-このコードはメモリから書き込まれ、テストされていません。