【问题标题】:client-server ipc message 2 pipes communication simple example客户端-服务器 IPC 消息 2 管道通信简单示例
【发布时间】:2011-09-11 08:13:57
【问题描述】:

我想通过 2 个半双工管道发送和接收消息

数据流 上半管 标准输入--->父(客户端)fd1[1]--->管道1-->子(服务器)fd1[0] 下半管 子(服务器)fd2[1]---->pipe2--->父(客户端)fd2[0]--->stdout

我需要有边界结构化消息mesg_len+mesg_type+mesg_data

功能是如果用户在stdin上输入“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);
}

【问题讨论】:

    标签: c unix ipc pipe message-queue


    【解决方案1】:

    您的第一个问题是因为您颠倒了客户端函数的参数。读取的描述符总是描述符 0。所以你的代码应该是这样的:

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

    但您的问题远不止于此。你正在以错误的方式做这个标题/数据的事情。不要将结构写成 IPC 机制。这会给您带来很多困难,尤其是当您从使用管道过渡到使用 TCP 套接字时。

    例如,在我的系统上,标头大小是 16 字节,而不是 8。sizeof mymesg 是 104,而不是 100。这是因为我在 64 位系统上运行,而在我的系统上,long 是8 字节,它还可以将结构填充为 8 字节的倍数。

    我可能会在第二部分为您提供进一步的帮助。但我需要更多地了解您的想法以及您使用它的目的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-02
      • 1970-01-01
      • 2012-09-27
      相关资源
      最近更新 更多