【发布时间】:2017-03-04 09:12:39
【问题描述】:
我正在为嵌入在我的路由器中的 3g 调制解调器开发显示器。 在linux系统中作为/dev/ttyUSB设备接口。
我需要使用非阻塞读取,我将使用 select()。 这是代码:
df = open(MODEMDEVICE, O_RDWR|O_EXCL);
if (df <0) {perror(MODEMDEVICE); exit(-1); }
tv.tv_sec = 5;
tv.tv_usec = 0;
FD_ZERO(&rfds);
FD_SET(df, &rfds);
while (1) {
retval = select(df+1, &rfds, NULL, NULL, &tv);
if (retval == -1)
perror("select()");
else if (retval) {
rdnum=read(df, rdbuf, MSGBUFFSIZE-1);
rdbuf[rdnum]='\0';
if (rdnum == 1)
printf("data available(%i-%i): 0x%02x\n",retval , rdnum, rdbuf[0]);
else
printf("data available(%i-%i):%s\n",retval , rdnum, rdbuf);
usleep(200000);
} else
printf("No data within five seconds.\n");
}
但输出是这个:
data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-17):+PSBEARER: 24, 8
data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-17):+PSBEARER: 24, 3
data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-17):+PSBEARER: 24, 8
data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-1): 0x0a
data available(1-17):+PSBEARER: 24, 3
似乎每次调用 select() 时都会立即返回,而当调用 read() 时,如果没有可用的实际数据,也会返回 0x0a(换行符)。
通过使用 picom 进行交谈,我得到:
+PSBEARER: 24, 8
+PSBEARER: 24, 3
+PSBEARER: 24, 8
+PSBEARER: 24, 3
它不显示换行,并且在“+PSBEARER: 24, 3”代码之后有更大的滞后。
我哪里错了? 谢谢。
【问题讨论】:
-
man select: 在 Linux 下,select() 可能会将套接字文件描述符报告为“准备好读取”,但随后的读取会阻塞。例如,当数据到达但检查时校验和错误并被丢弃时,可能会发生这种情况。可能存在文件描述符被虚假报告为就绪的其他情况。因此,在不应阻塞的套接字上使用 O_NONBLOCK 可能更安全。