"TCP/IP Network Programming" reading notes - inter-process communication

Table of contents

1--Inter-process communication

2--pipe() function

3--Code examples

3-1--pipe1.c

3-2--pipe2.c

3-3--pipe3.c

3-4--Echo server side that saves information


1--Inter-process communication

        In order to realize inter-process communication so that data can be exchanged between two different processes, the operating system must provide a memory space that two processes can access simultaneously;

        In order to complete inter-process communication, a pipe needs to be created; the pipe does not belong to the resource of the process, but belongs to the operating system;

2--pipe() function

#include <unistd.h>
int pipe(int filedes[2]);
// 成功时返回0,失败时返回-1
// filedes[0] 通过管道接收数据时使用的文件描述符,即管道出口
// filedes[1] 通过管道传输数据时使用的文件描述符,即管道入口

3--Code examples

3-1--pipe1.c

        The child process writes data from the pipe entrance, and the parent process reads data from the pipe exit;

// gcc pipe1.c -o pipe
// ./pipe

#include <stdio.h>
#include <unistd.h>
#define BUF_SIZE 30

int main(int argc, char *argv[]){
    int fds[2];
    char str[] = "Who are you?";
    char buf[BUF_SIZE];
    __pid_t pid;

    pipe(fds); // 创建管道
    pid = fork();
    if(pid == 0){ // 子进程执行区域
        write(fds[1], str, sizeof(str)); // 向管道入口写数据
    }
    else{ // 父进程执行区域
        read(fds[0], buf, BUF_SIZE); // 向管道出口读数据
        puts(buf);
    }
    return 0;
}

3-2--pipe2.c

        Use a pipeline to realize two-way communication between the parent process and the child process;

// gcc pipe2.c -o pipe2
// ./pipe2

#include <stdio.h>
#include <unistd.h>
#define BUF_SIZE 30

int main(int argc, char *argv[]){
    int fds[2];
    char str1[] = "Who are you?";
    char str2[] = "Thank you for your message";
    char buf[BUF_SIZE];
    __pid_t pid;

    pipe(fds); // 创建管道
    pid = fork();
    if(pid == 0){ // 子进程执行区域
        write(fds[1], str1, sizeof(str1)); 
        sleep(2); // sleep的作用是防止子线程写的数据被子线程自身读取了,导致父进程一直等待
        read(fds[0], buf, BUF_SIZE);
        printf("Child proc output: %s \n", buf);
    }
    else{ // 父进程执行区域
        read(fds[0], buf, BUF_SIZE); 
        printf("Parent proc output: %s \n", buf);
        write(fds[1], str2, sizeof(str2));
        sleep(3);
    }
    return 0;
}

3-3--pipe3.c

        Use two pipelines to realize two-way communication between the parent process and the child process, in which data is sent and received on different pipelines;

// gcc pipe3.c -o pipe3
// ./pipe3

#include <stdio.h>
#include <unistd.h>
#define BUF_SIZE 30

int main(int argc, char *argv[]){
    int fds1[2], fds2[2];
    char str1[] = "Who are you?";
    char str2[] = "Thank you for your message";
    char buf[BUF_SIZE];
    __pid_t pid;

    pipe(fds1), pipe(fds2); // 创建管道
    pid = fork();
    if(pid == 0){ // 子进程执行区域
        write(fds1[1], str1, sizeof(str1)); // 通过管道1写数据
        read(fds2[0], buf, BUF_SIZE); // 通过管道2读数据
        printf("Child proc output: %s \n", buf);
    }
    else{ // 父进程执行区域
        read(fds1[0], buf, BUF_SIZE); // 通过管道1读数据
        printf("Parent proc output: %s \n", buf);
        write(fds2[1], str2, sizeof(str2)); // 通过管道2写数据
        sleep(3);
    }
    return 0;
}

3-4--Echo server side that saves information

        Create two processes on the server side, one process is responsible for communicating with the client, and writes the data sent by the client to the pipeline through the pipeline entrance; the other process is responsible for reading data from the pipeline exit and saving the read data in the file;

        Specific runnable code reference: Chapter11

// gcc echo_storeserv.c -o echo_storeserv
// ./echo_storeserv 9190

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define BUF_SIZE 30

void error_handling(char *message){
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

void read_childproc(int sig){
    __pid_t pid;
    int status;
    pid = waitpid(-1, &status, WNOHANG);
    printf("remove proc id: %d \n", pid);
}

int main(int argc, char* argv[]){
    int serv_sock, clnt_sock;
    struct sockaddr_in serv_adr, clnt_adr;
    int fds[2];

    __pid_t pid;
    struct sigaction act; // 信号
    socklen_t adr_sz;
    int str_len, state;
    char buf[BUF_SIZE];
    if(argc != 2){
        printf("Usage : %s <port>\n", argv[0]);
        exit(1);
    }

    act.sa_handler = read_childproc; //设置信号处理函数
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    state = sigaction(SIGCHLD, &act, 0);

    serv_sock = socket(PF_INET, SOCK_STREAM, 0); // 创建 tcp socket
    memset(&serv_adr, 0, sizeof(serv_adr));
    serv_adr.sin_family = AF_INET;
    serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_adr.sin_port = htons(atoi(argv[1]));

    if(bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr)) == -1){
        error_handling("bind() error"); 
    } 
    if(listen(serv_sock, 5) == -1){
        error_handling("listen() error");
    }

    pipe(fds);
    pid = fork();
    if(pid == 0){ // 子进程执行区域
        FILE* fp = fopen("echomsg.txt", "wt");
        char msgbuf[BUF_SIZE];
        int i, len;

        for(i = 0; i < 10; i++){
            len = read(fds[0], msgbuf, BUF_SIZE);
            fwrite((void*)msgbuf, 1, len, fp);
        }
        fclose(fp);
        return 0;
    }
    while(1){
        adr_sz = sizeof(clnt_adr);
        clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &adr_sz);
        if(clnt_sock == -1){
            continue;
        }
        else{
            puts("new client connected...");
        }

        pid = fork();
        if(pid == 0){
            close(serv_sock);
            while((str_len = read(clnt_sock, buf, BUF_SIZE)) != 0){
                write(clnt_sock, buf, str_len);
                write(fds[1], buf, str_len);
            }
            close(clnt_sock);
            puts("client disconnected...");
            return 0;
        }
        else{
            close(clnt_sock);
        }
    }
    close(serv_sock);
    return 0;

}

Guess you like

Origin blog.csdn.net/weixin_43863869/article/details/132779468