1

クライアントがサーバーのPIPEにコマンドを書き込むクライアントサーバープログラムがあります。サーバーからコマンドを読み取るときに、コマンドの最初の文字のみを読み取り、エラーをスローします。誰でもこれで私を助けることができますか?

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <sys/wait.h>
#include <mqueue.h>
#include <sys/stat.h>
#include "Functions.h"

#define MSGBUFFER_SIZE 50000

pid_t serverPid;
pid_t clientPid;

typedef struct msgbuf {

int messageLength;
int messageType;
char messageText[MSGBUFFER_SIZE];

} Message_buf;

int writePIPE(int fd, Message_buf *inputMessage){

printf("\n In write pipe message length :%d",inputMessage->messageLength);
printf("\n In write pipe message Data :%s",inputMessage->messageText);
ssize_t n=write(fd,inputMessage,inputMessage->messageLength);
printf("\n Size :%d", n);
return n;
}

ssize_t readPIPE(int fd, Message_buf *outputMessage)
{
ssize_t len;
ssize_t n;
if((n=read(fd,outputMessage,sizeof(outputMessage)))==0)
{
    printf("\n Error");
    return 0;
}
if((len=outputMessage->messageLength)>0)
{
    printf("\n Length ---->:%d",len);
    if((n=read(fd,outputMessage->messageText,strlen(outputMessage->messageText)))!=len)
        printf("\n ERRRRROR expected %d got %d",len,n);
}
//printf("\n In Read PIPE: %s",outputMessage->messageText);
return len;
}
void Server(int readfd,int writefd)
{
Message_buf server_MessageBuf;

ssize_t length;
if((length=readPIPE(readfd,&server_MessageBuf))==0)
{
    printf("\n End of file while reading pathname");
}
//server_MessageBuf.messageText[length]='\0';

printf("\n LENGTH :%d",server_MessageBuf.messageLength);
printf("\n Printing in server: %s\n",server_MessageBuf.messageText);

}
void Client(int readfd,int writefd)
{

char inputFileName[MAX_SIZE];
char inputOperation[MAX_SIZE];
char *cCommandInput = NULL;
char *fileOperation = NULL;
char *operation = (char *) malloc(MAX_SIZE);

int commandValidateStatus = 0;
int commandInterpretationStatus=0;
Message_buf client_MessageBuf;
for(;;)
{
    while(1)
    {
        cCommandInput = acceptInput();
        fileOperation = (char *) malloc(sizeof(cCommandInput));
        strcpy(fileOperation,cCommandInput);

        /**Function call to determine operation read/delete/exit/invalid choice and filename*****/
        commandInterpretationStatus = interpretCommand(cCommandInput,
                inputOperation, inputFileName);

        operation = inputOperation;

        /**Function call to validate the input command******/
        commandValidateStatus = validateCommand(
                commandInterpretationStatus, inputOperation, inputFileName);

        if(commandValidateStatus==-1)
        {
            printf("\n Invalid Operation");
        }

        /*Exit command entered***/
        if (commandValidateStatus == 1)
        {
            /*Code to clear resources */
            kill(serverPid,SIGKILL);
            kill(clientPid,SIGKILL);
            exit(0);
        }
        /***Read or Delete****/
        if (commandValidateStatus == 2 || commandValidateStatus == 3)
        {
            printf("\n Read or Delete\n");

            strcpy(client_MessageBuf.messageText,fileOperation);
            client_MessageBuf.messageLength=strlen(fileOperation);
            client_MessageBuf.messageType=1;
            if((writePIPE(writefd,&client_MessageBuf))<0)
            {
                printf("\n Error writing on client side ");
            }

            //read(readfd,*client_MessageBuf,sizeof(client_MessageBuf));
            //printf("\n Reding server responsed");
            //printf("%s",client_MessageBuf.messageText);
        }
    }
}

}

int main()
{
int pipe1[2],pipe2[2];
pipe(pipe1);
pipe(pipe2);

pid_t pid;
pid=fork();
serverPid=pid;

if(pid==0)
{
    /*Call Server*/
    close(pipe1[1]);
    close(pipe2[0]);
    Server(pipe1[0], pipe2[1]);   
}
else
{
    close(pipe1[0]);
    close(pipe2[1]);
    Client(pipe2[0],pipe1[1]);      
}
return 0;
}
4

1 に答える 1

0

コードの書き込みと読み取りstruct msgbufが正しくないようです。

typedef struct msgbuf {
    int messageLength;
    int messageType;
    char messageText[MSGBUFFER_SIZE];
} Message_buf;

// ...

strcpy(client_MessageBuf.messageText,fileOperation);
client_MessageBuf.messageLength=strlen(fileOperation);
client_MessageBuf.messageType=1;
if((writePIPE(writefd,&client_MessageBuf))<0)

// ....

int writePIPE(int fd, Message_buf *inputMessage){
    printf("\n In write pipe message length :%d",inputMessage->messageLength);
    printf("\n In write pipe message Data :%s",inputMessage->messageText);
    ssize_t n=write(fd,inputMessage,inputMessage->messageLength);
    printf("\n Size :%d", n);
    return n;
}

上記の書き込み部分は、メンバーの長さを含まない構造体struct msgbufの最初のバイトのみを書き込みます。つまり、オブジェクトを切り捨てます。messageLengthmessageLengthmessageType

読むとき:

ssize_t readPIPE(int fd, Message_buf *outputMessage)
{
    // ...
    if((n=read(fd,outputMessage,sizeof(outputMessage)))==0)

sizeof(outputMessage)オブジェクトではなく、ポインターのサイズであるバイトのみを読み取ります。に変更して修正したとしてもsizeof(*outputMessage)、完全なオブジェクトを読み取ることが期待されるため、十分ではありませんが、書き込み部分はオブジェクトを切り捨てます。

これを修正するには、メッセージをヘッダーとペイロードの 2 つの部分に分割することから始めるのがよいでしょう。ヘッダーは、固定サイズの構造体です。たとえば、次のようになります。

typedef struct {
    int messageType;
    int payloadLength;
} MessageHeader;

ペイロードは、ヘッダーに続く可変長部分です。このようにして、最初にヘッダー オブジェクト全体をパイプに書き込み、続いてpayloadLengthペイロードのバイトを書き込みます。読み取るときは、最初にヘッダー全体を再度読み取り、次に正確にpayloadLengthバイトを読み取ります。

read()また、 and の呼び出しは、要求された数より少なく読み取りまたは書き込みを行う可能性があることに注意してください。そのwrite()ため、正確なバイト数が処理されるまで、読み取りまたは書き込みを続けることによって、ケースを明示的に処理する必要があります。

于 2012-05-07T12:32:31.950 に答える