3

Two programs that communicate with FIFOs work with the loop, but not with the wh...

 3 years ago
source link: https://www.codesd.com/item/two-programs-that-communicate-with-fifos-work-with-the-loop-but-not-with-the-while-loop.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Two programs that communicate with FIFOs work with the loop, but not with the while loop

advertisements

I am trying to write two programs that will communicate via FIFOs in C. I am experimenting with FIFOs for an assignment I have.

When I know the number of messages and read them with a for loop, it prints out all the messages that were sent from the other side. If I use a while loop, it only sends two of them. The code is slightly changed from this question How to send a simple string between two programs using pipes?

This works:

/* writer */
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    int fd;
    char * myfifo = "/tmp/myfifo";

    /* create the FIFO (named pipe) */

    /* write "Hi" to the FIFO */
    fd = open(myfifo, O_WRONLY);
    int i;
    for(i = 0; i < 10; i++)
         write(fd, "Hi", sizeof("Hi"));
    close(fd);

    return 0;
}

And: (edited)

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

#define MAX_BUF 1024

int main()
{
    int fd;
    char * myfifo = "/tmp/myfifo";
    char buf[MAX_BUF];

     mkfifo(myfifo, 0666);
    /* open, read, and display the message from the FIFO */
    fd = open(myfifo, O_RDONLY);
    int i;
    for(i = 0; i < 10; i++)
    {
        int n = read(fd, buf, MAX_BUF);
        printf("n = %d , Received: %s\n",n, buf);
    }
    close(fd);

     /* remove the FIFO */
    unlink(myfifo);

    return 0;
}

Edit: This now prints

n = 18 , Received: Hi
n = 12 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi

When I change the reader to this, it doesn't work:

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

#define MAX_BUF 1024

int main()
{
    int fd;
    char * myfifo = "/tmp/myfifo";
    char buf[MAX_BUF];

     mkfifo(myfifo, 0666);
    /* open, read, and display the message from the FIFO */
    fd = open(myfifo, O_RDONLY);
    int i;
    while(read(fd, buf, MAX_BUF))
        printf("Received: %s\n", buf);

    close(fd);

     /* remove the FIFO */
    unlink(myfifo);

    return 0;
}

I am running the two programs in two separate terminals and all. When I run them with the second reader, it only prints out:

Received: Hi
Received: Hi

Any help would be appreciated.


Pipes are stream based, not message based. While the number of bytes read should match the number written, the number of read calls is not necessarily the same as the number of write calls.

If we modify the reader to print the number of bytes received:

int len;
while((len=read(fd, buf, MAX_BUF)) > 0) {
    printf("Received %d: %s\n", len, buf);
}

I get the following output:

Received 30: Hi

So in the second case, there are 10 writes of 3 bytes (2 for the letters H and i and one for the null terminating byte) and 1 read of 30 bytes. The reason 3 bytes is being written on each write call is because the string constant "Hi" has type char [3].

You only see one instance of "Hi" printed because the third byte is a null byte which terminates the string, so nothing past that is printed.


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK