Comment envoyer une chaîne simple entre deux programmes en utilisant des tuyaux?

J'ai essayé de chercher sur le net, mais il n'y a pratiquement pas de ressources. Un petit exemple suffit.

Modifier Je veux dire, deux programmes C différents communiquant entre eux. Un programme devrait envoyer "Salut", et l'autre doit le recevoir. Quelque chose comme ça.

96
demandé sur jschmier 2010-05-07 01:06:37

7 réponses

Un tuyau ordinaire ne peut connecter que deux processus connexes. Il est créé par un processus et disparaîtra lorsque le dernier processus de la ferme.

Un tube nommé, aussi appelé une FIFO de son comportement, peut être utilisé pour connecter deux indépendants des processus et existe indépendamment du processus, ce qui signifie qu'il peut exister, même si personne ne l'utilise. Un FIFO est créé en utilisant le mkfifo() bibliothèque fonction.

Exemple

De l'Écrivain.c

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    int fd;
    char * myfifo = "/tmp/myfifo";

    /* create the FIFO (named pipe) */
    mkfifo(myfifo, 0666);

    /* write "Hi" to the FIFO */
    fd = open(myfifo, O_WRONLY);
    write(fd, "Hi", sizeof("Hi"));
    close(fd);

    /* remove the FIFO */
    unlink(myfifo);

    return 0;
}

Lecteur.c

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#define MAX_BUF 1024

int main()
{
    int fd;
    char * myfifo = "/tmp/myfifo";
    char buf[MAX_BUF];

    /* open, read, and display the message from the FIFO */
    fd = open(myfifo, O_RDONLY);
    read(fd, buf, MAX_BUF);
    printf("Received: %s\n", buf);
    close(fd);

    return 0;
}

Remarque: la vérification des erreurs a été omise du code ci-dessus pour plus de simplicité.

145
répondu jschmier 2010-05-07 16:08:09

À partir de en créant des tuyaux en C , cela vous montre comment bifurquer un programme pour utiliser un tuyau. Si vous ne voulez pas de fork(), vous pouvez utiliser canaux nommés.

En outre, vous pouvez obtenir l'effet de prog1 | prog2 en envoyant la sortie de prog1 à stdout et en lisant à partir de stdin dans prog2. Vous pouvez également lire stdin en ouvrant un fichier nommé /dev/stdin (mais pas sûr de la portabilité de cela).

/*****************************************************************************
 Excerpt from "Linux Programmer's Guide - Chapter 6"
 (C)opyright 1994-1995, Scott Burkett
 ***************************************************************************** 
 MODULE: pipe.c
 *****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

int main(void)
{
        int     fd[2], nbytes;
        pid_t   childpid;
        char    string[] = "Hello, world!\n";
        char    readbuffer[80];

        pipe(fd);

        if((childpid = fork()) == -1)
        {
                perror("fork");
                exit(1);
        }

        if(childpid == 0)
        {
                /* Child process closes up input side of pipe */
                close(fd[0]);

                /* Send "string" through the output side of pipe */
                write(fd[1], string, (strlen(string)+1));
                exit(0);
        }
        else
        {
                /* Parent process closes up output side of pipe */
                close(fd[1]);

                /* Read in a string from the pipe */
                nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
                printf("Received string: %s", readbuffer);
        }

        return(0);
}
37
répondu Stephen 2014-07-11 16:18:26
dup2( STDIN_FILENO, newfd )

Et lire:

char reading[ 1025 ];
int fdin = 0, r_control;
if( dup2( STDIN_FILENO, fdin ) < 0 ){
    perror( "dup2(  )" );
    exit( errno );
}
memset( reading, '\0', 1025 );
while( ( r_control = read( fdin, reading, 1024 ) ) > 0 ){
    printf( "<%s>", reading );
    memset( reading, '\0', 1025 );
}
if( r_control < 0 )
    perror( "read(  )" );    
close( fdin );    

, Mais, je pense que fcntl peut être une meilleure solution

echo "salut" | code
8
répondu mlouk 2011-08-14 10:05:55

Ce qu'un programme écrit sur stdout peut être lu par un autre via stdin. Donc simplement, en utilisant c, écrivez prog1 pour imprimer quelque chose en utilisant printf() et prog2 pour lire quelque chose en utilisant scanf(). Ensuite, exécutez simplement

./prog1 | ./prog2
6
répondu Johan 2010-05-06 21:14:56

Voici un échantillon de:

int main()
{
    char buff[1024] = {0};
    FILE* cvt;
    int status;
    /* Launch converter and open a pipe through which the parent will write to it */
    cvt = popen("converter", "w");
    if (!cvt)
    {
        printf("couldn't open a pipe; quitting\n");
        exit(1)
    }
    printf("enter Fahrenheit degrees: " );
    fgets(buff, sizeof (buff), stdin); /*read user's input */
    /* Send expression to converter for evaluation */
    fprintf(cvt, "%s\n", buff);
    fflush(cvt);
    /* Close pipe to converter and wait for it to exit */
    status=pclose(cvt);
    /* Check the exit status of pclose() */
    if (!WIFEXITED(status))
        printf("error on closing the pipe\n");
    return 0;
}

Les étapes importantes de ce programme sont:

  1. l'appel popen() qui établit l'association entre un processus enfant et un canal dans le parent.
  2. l'appel fprintf() qui utilise le canal comme un fichier ordinaire pour écrire dans le stdin du processus enfant ou lire à partir de son stdout.
  3. l'appel pclose() qui ferme le canal et provoque la fin du processus enfant.
3
répondu Preet Sangha 2013-04-23 16:22:09

Tout d'abord, demandez au programme 1 d'écrire la chaîne dans stdout (comme si vous vouliez qu'elle apparaisse à l'écran). ensuite, le deuxième programme devrait lire une chaîne de stdin, comme si un utilisateur tapait à partir d'un clavier. ensuite, vous exécutez:

Program_1 / program_2

2
répondu lfagundes 2010-05-06 21:12:44

Cette réponse pourrait être utile pour un futur Googleurs.

#include <stdio.h>
#include <unistd.h>

int main(){     
     int p, f;  
     int rw_setup[2];   
     char message[20];      
     p = pipe(rw_setup);    
     if(p < 0){         
        printf("An error occured. Could not create the pipe.");  
        _exit(1);   
     }      
     f = fork();    
     if(f > 0){
        write(rw_setup[1], "Hi from Parent", 15);    
     }  
     else if(f == 0){       
        read(rw_setup[0],message,15);       
        printf("%s %d\n", message, r_return);   
     }  
     else{      
        printf("Could not create the child process");   
     }      
     return 0;

}

Vous pouvez trouver un exemple d'appel bidirectionnel avancé ici .

1
répondu Anjana 2017-10-25 02:43:26