客户端-服务器 ipc 消息 2 管道通信简单示例

发布于 2024-11-14 11:03:30 字数 2690 浏览 2 评论 0原文

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

数据流 上半管 stdin--->父级(客户端)fd1[1]--->pipe1-->子级(服务器)fd1[0] 下半管 child(server) fd2[1]---->pipe2--->parent(client) 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);
}

I want to have a message send & receive through 2 half-duplex pipes

Flow of data
top half pipe
stdin--->parent(client) fd1[1]--->pipe1-->child(server) fd1[0]
bottom half pipe
child(server) fd2[1]---->pipe2--->parent(client) fd2[0]--->stdout

I need to have boundary structed message mesg_len+mesg_type+mesg_data

The function is that if user input "Knock Knock" on stdin, which directs to client, client send this message to server on the top half pipe, server compares the string, if matches with "Knock Knock", then server reply message "Who's there?" to client throught the bottom half pipe, and client write this message to the stdout.

Below is my code:
I have a problem:

  1. when the server starts, the message is empty, when i type anything on the console, I got mesg_headersize and mesg_datasize both -1. Program can't continue. How to solve this problem?

Please help. Many thanks.

#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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挽你眉间 2024-11-21 11:03:30

您的第一个问题是因为您颠倒了客户端函数的参数。读取描述符始终为描述符 0。因此您的代码应为:

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

但您遇到的问题比这要深得多。您将以错误的方式执行此标头/数据操作。不要将结构编写为 IPC 机制。这会给您带来许多困难,特别是如果您从使用管道过渡到使用 TCP 套接字。

举个例子,在我的系统上,标头大小是 16 个字节,而不是 8。并且 sizeof mymesg 是 104,而不是 100。这是因为我在 64 位系统上运行,并且在我的系统长整型为 8 字节,并且还将结构填充为 8 字节大小的倍数。

我可能可以帮助您进一步完成第二部分。但我需要更多地了解你的想法以及你用它来做什么。

Your first problem is because you reversed the arguments to your client function. The read descriptor is always descriptor 0. So your code should read:

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

But you have issues that are far deeper than that. You are going about doing this header/data thing in the wrong way. Do not write structures as an IPC mechanism. This will cause you numerous difficulties, especially if you transition from using pipes to using TCP sockets.

As an example, on my system, the header size is 16 bytes, not 8. And sizeof mymesg is 104, not 100. This is because I'm running on a 64 bit system, and on my system longs are 8 bytes, and it also pads structures to a multiple of 8 bytes in size.

I can probably help you further with the second part of this. But I will need to know more about what you were thinking and what you're using this for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文