клиент-сервер ipc сообщение 2 канала связи простой пример - PullRequest
0 голосов
/ 09 июня 2011

Я хочу получать и отправлять сообщения через 2 полудуплексных канала

поток данных верхняя половина трубы stdin ---> parent (клиент) fd1 [1] ---> pipe1 -> child (сервер) fd1 [0] нижняя половина трубы дочерний (сервер) fd2 [1] ----> pipe2 ---> родительский (клиент) fd2 [0] ---> stdout

Мне нужно иметь граничное сообщение mesg_len + mesg_type + mesg_data

Функция состоит в том, что если пользовательский ввод "Knock Knock" на стандартный ввод, который направляет клиенту, клиент отправляет это сообщение на сервер в верхней половине канала, сервер сравнивает строку, если совпадает с "Knock Knock", то ответ сервера сообщение "Кто там?" клиенту через нижнюю половину канала, и клиент пишет это сообщение на стандартный вывод.

Ниже мой код: У меня проблема:

  1. когда сервер запускается, сообщение пустое, когда я что-то печатаю на консоли, я получаю mesg_headersize и mesg_datasize и -1. Программа не может продолжаться. Как решить эту проблему?

Пожалуйста, помогите. Большое спасибо.

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

#define MAX_BUF 100
#define MAXMESGDATA (MAX_BUF - 2* sizeof(long))
#define MESGHDRSIZE (sizeof(struct mymesg)-MAXMESGDATA)

struct mymesg{
    long mesg_len; //byte in mesg_data
    long mesg_type; //message type
    char mesg_data[MAXMESGDATA];
};

ssize_t mesg_send(int,struct mymesg *);
ssize_t mesg_recv(int,struct mymesg *);
void client (int,int),server(int,int);

int main(int argc, char ** argv){
    //MAXMESGDATA== 92 bytes
    //sizeof(struct mymesg)== 100 bytes
    //2* sizeof(long)== 8 bytes
    //MESGHDRSIZE ==8 bytes

    int pipe1[2],pipe2[2];
    pid_t childpid;
    pipe(pipe1); //create 2 pipes
    pipe(pipe2);

    if ((childpid=fork())==0) { //child
        close(pipe1[1]);
        close(pipe2[0]);
        server(pipe1[0],pipe2[1]);
        exit(0);
    }
    //parent
    close(pipe1[0]);
    close(pipe2[1]);
    client(pipe1[1],pipe2[0]);
    waitpid (childpid,NULL,0);
    return EXIT_SUCCESS;
}

  void client(int readfd,int writefd){
    size_t len;
    ssize_t n;
    struct mymesg mesg;

    fgets(mesg.mesg_data,MAXMESGDATA,stdin);//read mesg
    len=strlen(mesg.mesg_data);

    if (mesg.mesg_data[len-1]=='\n') //ignore newline
        len--;
    mesg.mesg_len=len;
    mesg.mesg_type=1;
    mesg_send(writefd,&mesg);//write to IPC channel
    //read from IPC,write to std output
    while((n=mesg_recv(readfd,&mesg))>0)
        write(STDOUT_FILENO,mesg.mesg_data,n);

}

void server(int readfd,int writefd){
    ssize_t n;
    struct mymesg mesg;
    mesg.mesg_type=1;
    //read from IPC channel
    if ((n=mesg_recv(readfd,&mesg))==0){
        printf("Message missing");
        exit(1);
    }

    mesg.mesg_data[n]='\0';
    mesg.mesg_len=strlen(mesg.mesg_data);
    //printf("%s\n",mesg.mesg_data);

    if (strcasecmp ("Knock Knock", mesg.mesg_data)==0){
    char* str="Who's there?";
    strcpy(mesg.mesg_data,str);
    mesg.mesg_len=strlen(str)-1;
}
    mesg_send(writefd,&mesg);
}

1 Ответ

0 голосов
/ 09 июня 2011

Ваша первая проблема в том, что вы изменили аргументы своей клиентской функции.Дескриптор чтения всегда является дескриптором 0. Таким образом, ваш код должен читать:

client(pipe2[0],pipe1[1]);

Но у вас есть проблемы, которые намного глубже этого.Вы собираетесь делать это заголовок / данные неправильно.Не пишите структуры как механизм IPC.Это вызовет множество трудностей, особенно если вы переходите от использования каналов к использованию сокетов TCP.

Например, в моей системе размер заголовка составляет 16 байт, а не 8. И sizeof mymesg равен 104,не 100. Это потому, что я работаю в 64-битной системе, а в моей системе длинные 8 байтов, и это также дополняет структуры размером до кратного 8 байт.

Я, вероятно, могу вам помочьдалее со второй частью этого.Но мне нужно знать больше о том, что вы думали и для чего вы это используете.

...