Affan Zafar
Affan Zafar

Reputation: 41

Interprocess communication using pipes between C and python - only newlines are printing

I am making a project from which I want to retrieve hardware information using a C code and then plot it on python's library matplotlib.pylot. I want do this in real time so basically C code will keep on sending data to python script and the script will keep on plotting it on graph. I am trying to use named pipes to achieve my goal however when i print the data that python file has read from the pipe it just prints new line characters. When I use a C code to read the data from the pipe it prints the actual data that i wrote on that pipe. Following is the code of C file


#include <stdio.h> 
#include <string.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <errno.h>

int main()
{
    int fd;
    
    if(mkfifo("pipe1", 0777)==-1) 
    {
        if(errno != EEXIST)
        {
            printf("Could not create FIFO file.\n");
            return -1;
        }
    }

    printf("Opening...\n");
    fd = open("pipe1", O_WRONLY);
   
    int x=10;
   
    if(write(fd, &x, sizeof(int)) == -1)
    {
        printf("Write error\n");
        return 1;
    }
    x=2;
    write(fd,&x,sizeof(int));
    
    close(fd);
    printf("Closed\n");
    return 0;

}

Following is the code of python file

import os
import errno


FIFO = 'pipe1'

try:
    os.mkfifo(FIFO)
except OSError as oe: 
    if oe.errno != errno.EEXIST:
        print("Error occured")

with open(FIFO) as fifo:
    print("FIFO opened")
    while True:
        data = fifo.read()
        print(len(data))
        print(type(data))
        for e in data:
            print(e+ "a")
        
        if len(data) == 0:
            print("Writer closed")
            break
        #print(data)

Upvotes: 2

Views: 984

Answers (1)

Ofir
Ofir

Reputation: 138

There is no problem with the communication, the problem is in the way you parse the read data in your Python code.

The data that you write into the FIFO is in binary format - these are two integers, each of them is (probably) 4 bytes in memory. Your Python code interprets the data that it reads as a string of characters. In order to parse them properly, you can use the struct module.

For example:

... 
import struct

... 

# Note that we open in "rb" mode since struct expects bytes
with open(FIFO, "rb") as fifo:
    print("FIFO opened")
    while True:
        data = fifo.read(4)
        print(len(data))
        print(type(data))
        
        if len(data) == 0:
            print("Writer closed")
            break
        
        # Unpack a single integer in host byte order
        print(struct.unpack("=i", data)[0])

You can read more about the struct module and the format characters in the official documentation.

Upvotes: 2

Related Questions