Domanda

I have to implement a "printing server". I have 1 client file, and 1 server file:

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

int get_line( char *dest, int size );

#define MAX 1024

void main ()
{
    char const *pipe = "printservers";
    char buffer[MAX];
    int fd;

    get_line( buffer, MAX );

    if( mkfifo( pipe, 0666 ) < 0 )
    {
        printf( "Cannot create a pipe\n" );
        exit( EXIT_FAILURE );
    }

    fd = open( pipe, O_WRONLY );

    write( fd, buffer, MAX );

    close( fd );

    //unlink( pipe );

}

int get_line( char *dest, int size )
{
    int c, i;
    for( i = 0; i < size - 1 && ( c = getchar() ) != EOF && c != '\n'; ++i )
        dest[i] = c;
    if( c == '\n' )
    {
        dest[i] = c;
        ++i;
    }
    dest[i] = '\0';
    return i;
}

This is the client, which reads from the standard input a line and writes into a named pipe called printservers. This works as intended.

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

#define MAX_BUF 1024
#define MAX_PID 8

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

    /* open, read, and display the message from the FIFO */
    fd = open( myfifo, O_RDONLY );
    while( 1 )
    {
        if( read( fd, buf, MAX_BUF ) > 0 )
            printf("Received: %s\n", buf);
    }
    close(fd);

    return 0;
}

This is the server, which are read from the pipe. But it does not work with the while loop. If i send a message from the client, the first message is printed, but the following messages are ignored. Could somebody help me with my problem? Thanks Patrik

È stato utile?

Soluzione

There is a coding error in the server's while loop - the server will never exit the loop even when there is an error or the server receives eof on the FIFO. It should be changed to something like this:

while(1)
{
    if((bytesread = read( fd, buf, MAX_BUF - 1)) > 0)
    {
        buf[bytesread] = '\0';
        printf("Received: %s\n", buf);
    }
    else
        break;
}

Your other problem is that your client sends a single line and then closes the FIFO. The server reads until EOF. So it is going to read the single line, then hit EOF because the client closed. This is completely normal.

Where it becomes a problem is when you want your server to provide service to multiple clients. In that case you don't want to quit reading after every individual client closes its end. The semantics are such that the server will only see EOF after the last of all clients close. So an easy way to accommodate the server handling multiple clients is to open your server-side FIFO as read/write. Then there will always be a "writer", the server itself, with write end of the FIFO open. This will prevent the server from seeing EOF until you decide to shut it down.

A second problem is that you need to read and write in loops. You are not guaranteed to get your full data request filled in one call.

Also, having the client create the FIFO that the server reads is an odd approach. Normally you want the server to create a known FIFO to which clients connect.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top