Notas de lectura de "Programación de red TCP/IP" - Comunicación entre procesos

Tabla de contenido

1--Comunicación entre procesos

Función 2-tubería()

3--Ejemplo de código

3-1--tubería1.c

3-2--tubería2.c

3-3--pipe3.c

3-4--lado del servidor Echo que guarda información


1--Comunicación entre procesos

        Para implementar la comunicación entre procesos para que dos procesos diferentes puedan intercambiar datos, el sistema operativo debe proporcionar un espacio de memoria al que dos procesos puedan acceder al mismo tiempo;

        Para completar la comunicación entre procesos, es necesario crear una tubería, la tubería no pertenece al recurso del proceso, sino al sistema operativo;

Función 2-tubería()

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

3--Ejemplo de código

3-1--tubería1.c

        El proceso hijo escribe datos desde la entrada de la tubería y el proceso padre lee datos desde la salida de la tubería;

// 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--tubería2.c

        Utilice una tubería para lograr una comunicación bidireccional entre el proceso padre y el proceso hijo;

// 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

        Utilice dos canalizaciones para lograr una comunicación bidireccional entre el proceso principal y el proceso secundario, en la que los datos se envían y reciben en diferentes canalizaciones;

// 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--lado del servidor Echo que guarda información

        El servidor crea dos procesos. Un proceso es responsable de comunicarse con el cliente y escribir los datos enviados por el cliente en la tubería a través de la entrada de la tubería; el otro proceso es responsable de leer los datos de la salida de la tubería y guardar los datos leídos. el archivo;

        Referencia de código ejecutable específico: Capítulo 11

// 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;

}

Supongo que te gusta

Origin blog.csdn.net/weixin_43863869/article/details/132779468
Recomendado
Clasificación