0

FIFO について学んでいて、複数のクライアントからの要求を受け取る反復サーバーを作成しました。クライアントは、サーバーの既知の fifo に書き込むことによってファイルを要求します。サーバーはその FIFO から読み取り、要求されたファイルの内容をクライアントが読み取る新しい FIFO に入れます。サーバーを運営しています。初めてクライアントを実行すると、期待どおりに動作し、クライアントはファイルの内容を読み取ります。クライアントを 2 回目に実行すると、クライアントからのメッセージの前にバックスペース文字が付きます。このバックスペースがどこから来ているのかわかりません。何か案は?これはサーバーコードです:

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<fcntl.h>
#include<stdlib.h>
#include"fifo.h"

#define SERVFIFO "/tmp/fifo.serv"
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

int main(int argc, char** argv) {
    int readfifo, dummywrite, filefd, writefd, n;
    int clientpid;
    char buff[MAXLINE], *spaceptr, fifoname[MAXLINE];

    if (mkfifo(SERVFIFO, FILE_MODE) < 0 && errno != EEXIST) {
        printf("Can't create %s", SERVFIFO);
    }

    readfifo = open(SERVFIFO, O_RDONLY, 0);
    dummywrite = open(SERVFIFO, O_WRONLY, 0);

    while ((n = Readline(readfifo, buff, MAXLINE)) > 0) {
        printf("Read data from the fifo:%s and the length is:%d and the character is:%d\n", buff, strlen(buff), buff[0]);

        if (buff[n - 1] == '\n') {
            n--;
            printf("I am also omitting the newline\n");
        }

        buff[n] = '\0';
        printf("Buff just after read is:%s and length is %d", buff, strlen(buff));

        if ((spaceptr = strchr(buff, ' ')) == NULL) {
            printf("Bad request from client");
            continue;
        }

        printf("Found the space:%c\n", *(spaceptr + 1));
        *spaceptr++ = '\0';
        printf("The value of buffer now is:%s and the length of buffer is:%d and the culprit is %d\n", buff, strlen(buff), *(buff + 0));
        clientpid = atol(buff);
        printf("The client pid is %ld\n", clientpid);
        snprintf(fifoname, sizeof(fifoname), "/tmp/fifoname.%ld", clientpid);

        if (mkfifo(fifoname, FILE_MODE) < 0 && errno != EEXIST) {
            perror("Can't create the fifo");
            continue;
        }

        printf("Successfully created fifo %s for client\n", fifoname);

        if ((writefd = open(fifoname, O_WRONLY, 0)) < 0) {
            printf("Cannot open %s", fifoname);
            continue;
        }

        if ((filefd = open(spaceptr, O_RDONLY, 0)) < 0) {
            printf("Error opening file\n");
            continue;
        }
        else {
            while ((n = read(filefd, buff, MAXLINE))) {
                write(writefd, buff, n);
            }

            close(filefd);
            close(writefd);
        }
    }
}

これはクライアント コードです。

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

#define SERVER_FIFO "/tmp/fifo.serv"
#define MAXLINE 100
#define MSG "%ld sup.c"
#define READFIFO "/tmp/fifoname.%ld"
int main(int argc, char** argv) {
    int writefifo, readfifo, n;
    char buff[MAXLINE];
    pid_t self_pid = getpid();
    printf("Started client with PID:%ld\n", self_pid);
    writefifo = open(SERVER_FIFO, O_WRONLY, 0);
    snprintf(buff, sizeof(buff), MSG, self_pid);
    printf("The message to be written to the server is:%s and the length of the message is %d\n", buff, strlen(buff));

    if ((n = write(writefifo, buff, sizeof(buff))) != sizeof(buff)) {
        perror("Unable to write to server fifo");
        exit(0);
    }

    printf("Message written to the server; Waiting to read contents\n");
    snprintf(buff, sizeof(buff), READFIFO, self_pid);
    readfifo = open(buff, O_RDONLY, 0);

    while ((n = read(readfifo, buff, MAXLINE))) {
        write(STDOUT_FILENO, buff, n);
    }

    close(readfifo);
    close(writefifo);
    unlink(buff);
}
4

1 に答える 1

2

これは、説明した動作を表示しないため、実際のプログラムの切り刻まれたバージョンである可能性があります。いくつかのこと:

(1) サーバー内

readfifo = open(SERVFIFO, O_RDONLY, 0);
dummywrite = open(SERVFIFO, O_WRONLY, 0);

よく知られている fifo を相手側に何もない状態で開くと、オープンがブロックされることを知っていると思います。通常の状況では、クライアントの前にサーバーを実行するため、これはまだ O_RONLY オープンでブロックされます。ブロックを回避したい場合は、読み取り/書き込みとして一度開いてください。

(2) クライアント内

snprintf(buff, sizeof(buff), READFIFO, self_pid);
readfifo = open(buff, O_RDONLY, 0);

これはあなたが思っていることをしていません。クライアントがサーバーの fifo にメッセージを書き込み、サーバーがクライアントの fifo を作成しますmkfifo。クライアントが最初に実行されるため、これを行うと fifo は存在しませんopen。実際には、プレーン ファイル (存在しないファイル) を読み取り専用として開こうとしています。存在しないファイルを読み取ることはできないため、これopenは失敗しますが、開いているステータスを確認しないため、わかりません。

(3) 完了したら、FIFO のリンクを解除します。

于 2013-08-29T05:10:17.110 に答える