c - fgets 在提升为流的描述符中不阻塞

标签 c blocking fgets libc serial-communication

我在一个小型 C 程序中使用 fgets - 在 Ubuntu 下运行 - 通过 FTDI USB/串行转换器读取来自 Arduino 的数据。 我正在使用 GNU libc 中的低级 I/O 函数(因为我希望 - 将来 - 能够控制波特率等),然后从描述符提升到流,以便使用更高级别的 I/O 函数。 我的程序观察到的行为表明,在获取行终止符之前,fgets 函数不会阻塞(我认为它应该这样做)。

有什么解释吗?

我的程序代码在这里 -> PC端:

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

#define bufLen 81

int main(void) {
    int fd;    /* File descriptor for the port */
    FILE * f;  /* port will be identified also as stream 'f'*/
    char buf[bufLen];
    fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY);
    if (fd == -1) {perror(""); return errno;}
    else {
        f = fdopen(fd, "r+t");
        while (1) {
            if (fgets(buf,bufLen,f)) {
                printf("{%s}\n",buf);
                sleep(1);
            } else {
                {perror("ahhhh! ");}
            }
        }
    }
    return 0;
}

-> Arduino 端:

char ar[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
int k1 = 0, k2 = 0;

void setup() {
  // initialize serial:
  Serial.begin(9600);
}

void loop() {
  Serial.print(ar[k1]);
  k1 = (++k1) % 26;
  k2 = (++k2) % 5;
  if (k2==0) {Serial.println();}
  delay(300);
}

运行结果..

xxx@RevoR3600:~/CProg$ ./SerialPort
ahhhh! : Success
ahhhh! : Success
ahhhh! : Success
...
... (many identical lines...)
...
ahhhh! : Success
ahhhh! : Success
{AP}
{A}
{BCD}
{E
}
{FGHIJ
}
^C
xxx@RevoR3600:~/CProg$

最佳答案

在上面睡了一晚,又花了两个小时挖掘这个网站(和测试)之后,我终于在这里找到了一个解决方案;抱歉,我在发布之前无法找到它(我不明白为什么);现在,我需要确切地研究为什么找到的解决方案有效(以及为什么仍然存在一个小问题:在开始时获得一些奇怪的字符)。 感谢(并道歉)每个人都阅读了我的帖子。

这是工作(测试)代码:

#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<unistd.h>
#include<fcntl.h>
#include<termios.h>

#define bufLen 81

int main() {    

    char buf[bufLen];
    struct termios tty;
    FILE * f;
    int fd=open("/dev/ttyACM0",O_RDWR | O_NOCTTY);
    if(fd == -1) {
            perror("Unable to open /dev/ttyACM1\n");
            return -1;
    } else {
        if(tcgetattr(fd, &tty)!=0) {perror("tcgetatt() error"); return -1;}
        else {
            cfsetospeed(&tty, B9600);
            cfsetispeed(&tty, B9600);

            tty.c_cflag &= ~PARENB;
            tty.c_cflag &= ~CSTOPB;
            tty.c_cflag &= ~CSIZE;
            tty.c_cflag |= CS8;
            tty.c_cflag &= ~CRTSCTS; 
            tty.c_cflag |= CLOCAL | CREAD;

            tty.c_iflag |= IGNPAR | IGNCR;
            tty.c_iflag &= ~(IXON | IXOFF | IXANY);
            tty.c_lflag |= ICANON;
            tty.c_oflag &= ~OPOST;
            tcsetattr(fd, TCSANOW, &tty);

            if (!(f = fdopen(fd, "r+t"))) {perror("fdopen() error"); return -1;}

            while (1) {
                fgets(buf,bufLen,f);
                printf("%s--\n",buf);
            }   
        }
    }
    close(fd);
    return 0;
}

关于c - fgets 在提升为流的描述符中不阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21962467/

相关文章:

linux - 在 Linux 中,我正在寻找一种方法,让一个进程通过阻塞向另一个进程发出信号

javascript - 这是什么意思???当我使用 strongloop Controller API 时,Vanilla Node.js I/O 阻塞会消失吗?

c - 为什么 scanf 无法读取空格?

c - Endianness:这个宏在做什么?

c - PIC 将 SFR 地址传递给 C 语言中的函数

无法在 netbeans 中运行我的 C 代码

C: 如何在不记录 ENTER (\n) 的情况下获取用户输入?

c posix 正则表达式验证输入 HH :MM:SS time string

Java线程在不应该的地方停止执行

c - 如何将文件的内容存储到数组中(C)