花了几个小时在线研究这个问题,我仍然不清楚VTIME
和read(int fildes, void *buf, size_t nbyte);
如何一起工作。在我看来,只要read()
得到一个字节,它就会忽略VTIME
。只有在没有读取字节时才会服从VTIME
。
如果我正确读到这一点,here的解释似乎证实了这一点:
VMIN = 0且VTIME> 0 这是一个纯粹的定时阅读。如果输入队列中有数据,则会将其传送到调用者的缓冲区,最大为nbytes,并立即返回给调用者。否则,驱动程序将阻塞,直到数据到达,或者VTIME十分之一从呼叫开始到期。如果计时器在没有数据的情况下到期,则返回零。 单个字节足以满足此读取调用,但如果输入队列中有更多可用,则返回给调用者。请注意,这是一个整体计时器,而不是一个字符计时器。
是否有任何方法可以在 例如,在下面的代码中,read()
满足时或在最后一个字节后达到nbyte
时返回VTIME
?< / p>
VTIME
和read()
以这种方式行事似乎有点奇怪。为什么在超时之前不会尝试阅读nbytes
?read()
在返回之前不会等待10秒。如果没有发生写入,那么它就会发生。int main (void) {
int usbSerial;
struct termios options;
std::string port = "/dev/tty.usb001";
usbSerial = open(port.c_str(), O_RDWR| O_NOCTTY | O_NONBLOCK);
// Check if unopen
if(usbSerial == -1) {
printf("Error: Unable to open %s\n", port.c_str());
}
else { // Set to blocking
fcntl(usbSerial, F_SETFL, 0);
printf("Connection to serial device established.\n");
}
// Set port settings
tcgetattr(usbSerial, &options); // read old port settings
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
options.c_cflag &= ~PARENB; // set no parity, 1 stop bit, data bits
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~CRTSCTS; // no flow control.
options.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 100;
// Flush port and then apply new options
tcflush(usbSerial, TCIOFLUSH);
if (tcsetattr(usbSerial, TCSANOW, &options) != 0) { // TCSANOW == make option change immediately
printf("Error %i from tcsetattr.\n", errno);
}
// write
unsigned char message[] = {0x03, 0x05, 0x01, 0x01, 0x04};
ssize_t n = write(usbSerial, &message, sizeof(message)/sizeof(message[0]));
unsigned char buffer[64] = {};
tcdrain(usbSerial);
ssize_t readChars = read(usbSerial, &buffer, 10);
printf("Done.\n");
}
答案 0 :(得分:0)
当你说:
时,我相信你是对的在我看来,只要read()得到一个字节,它就会忽略VTIME。
read()
的返回值:
成功时,返回读取的字节数(零表示文件结束),文件位置按此编号前进。如果此数字小于请求的字节数,则不是错误;这可能发生,例如因为现在实际可用的字节数较少(可能是因为我们接近文件结尾,或者因为我们正在读取管道,或来自终端),或者因为read()被信号打断了。 link
您可能需要循环,可能类似(未经测试):
int totalNeeded = 10;
int remaining = 10;
while (remaining > 0){
ssize_t readChars = read(usbSerial, &buffer[totalNeeded - remaining], remaining);
if (readChars > 0){
remaining -= readChars;
}
else{
// handle error or EOF
}
}
不确定您需要如何处理部分读取,尤其是因为O_NONBLOCK
,但我认为VTIME与read()
之间的行为互动受read()
控制。