我正在管道中写入一些整数,结束时我写“ 11”。然后,当我从同一管道读取数据时,我必须取整数并对其进行处理,当我得到“ 11”时,我应该终止。但是我无法考虑可以在管道中同时读取int和char的任何解决方案(我知道这是基于fifo方法工作的。)
有什么想法吗?
//THIS IS AN EXAMPLE CODE OF WHAT I WANT TO DO
//I am writing to the pipe
while(CONDITION)
write(mypipe, &random_int, sizeof(short));
write(mypipe, "1", sizeof("11"));
/* code... */
//I am reading from the pipe
while(TRUE){
read(mypipe, &received_int, sizeof(short));
// if strcmp(receiver_int, "11")==0 then exit;
// else do stuff with receiver_int
}
答案 0 :(得分:1)
即使您将读取的字节正确地解释为16位整数和2字符串“ 11”(ASCII中为字节31 31
),管道也只是字节流,那么如何分辨“除整数12593外还有11英寸?它们具有相同的二进制表示形式。
一个选择是保持读取直到管道终止,这可能适合传输文件。但是不允许持续的来回消息。
write(mypipe, &random_int, sizeof(short));
close(mypipe); // finished writing
// recv
while (true)
{
short received_int;
if (read(mypipe, &received_int, sizeof(short)) == sizeof(short)) // Not handling the int getting split into two separate read's here
{
// Use received_int
}
else return; // 0 on close
}
这就是为什么大多数协议在流(文本或二进制)顶部引入消息概念的原因。例如,您可能有一个8位的“操作码”,并说0是“断开连接”,而1是“带有整数的消息”,那么写一个整数:
unsigned char opcode = 1;
short random_int = 55; // Make sure it actually a short, as you used sizeof(short)!
write(mypipe, &opcode, 1);
write(mypipe, &random_int, sizeof(short));
要阅读,请先阅读操作码,然后再决定:
char opcode;
read(mypipe, &opcode, 1); // CHECK RETURN!
switch (opcode)
{
case 0: return; // Finished
case 1:
{
short received_int;
read(mypipe, &received_int, sizeof(short)); // CHECK RETURN!
// Use received_int
break;
}
}
您可能会查看一些现有协议,了解它们如何将不同的事物编码到字节流中。
答案 1 :(得分:0)
我想说什么解决方案,可以在管道中同时读取int和char
对于本身来说,没有任何解决方案,因为一个人从管道中既不读取字符也不读取整数,而是读取原始字节。其他所有内容都是关于字节如何解释。
(我知道这是根据fifo方法工作的。)
FIFO具有与管道完全相同的约束。
通常来说,如果要跨任何个通信介质传递不同类型的对象,则需要某种格式或协议,以使接收者能够将数据解释为发送者想要的。范围从非常简单到非常复杂。您所描述的是一个特别简单的协议(实际上非常简单):数据由字节对组成,每个对都解释为无符号整数的字节,只是有一个特殊的两字节标记数据结束的顺序。
对于这样的协议,我可以这样写接收方:
union {
uint16_t num;
char s[3]; // Three bytes, not two, to allow for a terminator
} buffer = { .s = { 0 }};
while (1){
read(mypipe, &buffer, sizeof(uint16_t));
if (strcmp(buffer.s, "11") == 0) {
break;
}
// do stuff with buffer.num ...
}
但是不,您所描述的协议没有提供一种方法来区分"11"
的两个字节和用作整数值的两个相同的字节。结果,存在一个不能通过此协议发送的整数值。很有可能是12593(十进制),这是由于将"11"
的字符编码为ASCII,然后将结果重新解释为两个字节的整数而产生的。