简体   繁体   English

C 中的 Read() 但无需等待 EOF 字符

[英]Read() in C but without waiting for EOF character

I am doing some embedded programming using Python for the PC side and C for a controller side.我正在使用 Python 为 PC 端和 C 为 controller 端做一些嵌入式编程。 Serial reading in python is easy in a sense that you can read a certain amount of bytes, but I am having,,problems,, with reading in C. python 中的串行读取在某种意义上很容易,您可以读取一定数量的字节,但我在读取 C 时遇到问题。 Is it possible to read, for example 5 bytes, without waiting for the 'EOL' character('\n' or 0x0a)?是否可以读取,例如 5 个字节,而无需等待“EOL”字符(“\n”或 0x0a)? For now, I am adding '\n' at the end of every buffer transmitted from PC to controller but I would like to get rid of that since there is around 1 in 255 chance of failing the transmission (for every byte sent) if byte gets the value b'\x0a' and I always know the number of bytes I should expect from the value of the first byte.现在,我在从 PC 传输到 controller 的每个缓冲区的末尾添加 '\n' 但我想摆脱它,因为如果 byte得到值 b'\x0a' 并且我总是知道我应该从第一个字节的值中期望的字节数。 Thanks in advance everyone:-)在此先感谢大家:-)

this is a part of the function这是 function 的一部分

void recv(int port){          //function to receive buffer
//we are gonna receive a message and since this is an echo type of program we will signal
//signal thread to loop it back around
printf("Opened connection on port:%d \n",port);
while(1){
    if(stop){
        break;
    }
    //values are simulated with rand(), there is 10% movement to fall out of range
    voltage=rand_value(VOLTAGE_MIN-100000,VOLTAGE_MAX+100000);
    current=rand_value(CURRENT_MIN-100000,CURRENT_MAX+100000);
    temperature=rand_value(TEMP_MIN-30,TEMP_MAX+30);

    int nread;
    ioctl(port, FIONREAD, &nread);
    if (nread > 0) {
        memset(buf,0,sizeof(buf));
        int n=read(port,&buf,nread);  //blocking operation, it waits for "\n"
        /* for(int i=0; i<BUF_LEN; i++){
            //printf("Msg received: %s",buf);
            printf("buf index %d, data 0x%x \n", i, buf[i]);
        } */
        req=buf[0];                     //here we have command ID + data ID
                                        //                2bit        6bit
        printf("Bytes received: %d, req= 0x%x\n",n,req);    //prints the register and count of data received (always gets one above the actual data!)
        switch (((req&0b11000000)>>6)){     //SWITCHES COMMAND ID-S

this is opening the port in main这是在 main 中打开端口

   int port=open("/dev/ttyPS1",O_RDWR);

in between these 2 goes termios setup在这两个之间进行termios设置

    recv(port);

so even tho i use number of available bytes it completely ignores that and waits for the 0x0a value所以即使我使用可用字节数,它也会完全忽略它并等待 0x0a 值

You can use the read system call (or fread for FILE*).您可以使用 read 系统调用(或 FILE* 的 fread)。

Usage with file descriptor:与文件描述符一起使用:

int fd = STDIN_FILENO; // or your stream
int max_len = 10;
char buffer[max_len];
int actual_len = read(fd, buffer, max_len);
if (actual_len < 0) {
    exit(1); // error
}

Usage with FILE*:与 FILE* 一起使用:

FILE* file = stdin; // or your stream
int max_len = 10;
char buffer[max_len];
int actual_len = fread(file, buffer, max_len);
if (actual_len < 0) {
    exit(1); // error
}

The read systemcall reads up to n bytes into a buffer and returnes the number it could read. read 系统调用最多读取 n 个字节到缓冲区中并返回它可以读取的数字。 So if your stream has "hello" (without null terminator) as content, it will return 5.因此,如果您的 stream 有“hello”(没有 null 终止符)作为内容,它将返回 5。

And also I think you missunerstood EOF.而且我认为你误解了EOF。 EOF isn't actually a transmitted byte, it is a placeholder for stdio to signal that no more bytes were availible. EOF 实际上不是传输的字节,它是 stdio 的占位符,表示没有更多可用的字节。 Depending on the settings of the stream it can happen that you never get a EOF and the process just blocks until the stream is closed.根据 stream 的设置,您可能永远不会收到 EOF,并且该过程只会阻塞,直到 stream 关闭。

So from thinking about things people said in the comments and reading a recommended question this post about buffer reading I made it work pretty much as I was trying for days因此,通过思考人们在评论中所说的内容并阅读这篇关于缓冲区读取的推荐问题,我让它工作得非常好,就像我尝试了几天一样

I used this time flags where BUF_LEN is defined constant of the max possible buffer received What I don't like about this solution is that it is load depended but it is what it is.我使用了这个时间标志,其中 BUF_LEN 被定义为接收到的最大可能缓冲区的常量 我不喜欢这个解决方案是它依赖于负载,但它就是这样。

    tty.c_cc[VTIME] = 2;    // Wait for up to 0.2s (2 deciseconds), returning as soon as any data is received.
    tty.c_cc[VMIN] = BUF_LEN;

This is how communication in terminals looks like这就是终端通信的样子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM