2016-04-28 10 views
1

Ich weiß, es gibt eine Möglichkeit, dies in C zu programmieren, mit Gabel und Rohre in irgendeiner Weise machen (Ich weiß, es gibt einen Weg, ich weiß nicht, wie zu tun ist es zwar).Redirect Ausgang von Programm A zu Programm B und umgekehrt

Die beabsichtigte Verwendung ist die Verbindung einer Serverausgabe (die ich mit netcat bekommen würde) zu einem eigenen Programm in C++, das die Ausgabe verarbeitet und Netcat zurückgibt. Ich habe keine Ahnung, wie man direkt in C++ verbindet (Sockets sind mysteriöse Wesen) und ich möchte Boost vermeiden, da es in mehr oder weniger Vanilla-Systemen kompilieren sollte.

Gibt es also eine Möglichkeit, bash zu verwenden, um die Ausgabe eines Programms an den Eingang eines anderen Programms umzuleiten, und die Ausgabe des zweiten an die Eingabe des ersten in bash?

+0

Welche Implementierung von Netcat? Einige können tun, was Sie in C. beschrieben haben. –

+0

Der, der in ubuntu 'netcat-openbsd' kam. Es sagt, dass es eine Alternative gibt. Wenn es tun kann, was du sagst, wäre ich so glücklich :) – mjgalindo

Antwort

1

Angesichts einer Netcat-Implementierung haben Sie bereits, was Sie brauchen. Angenommen, Ihr Kunde /path/to/client genannt wird, Sie zu service.example.com am Port anschließen möchten 1234.

Entweder Ihr netcat ist wie ncat von nmap, dann können Sie tun:

ncat -c ``/path/to/client`` service.example.com 1234 

Wenn Ihr netcat ist minimalistisch, Sie hat ein Rohr zu verwenden:

mkdir pipes 
cd pipes 
mkfifo reverse_pipe 
/path/to/client < reverse_pipe | nc service.example.com 1234 > reverse_pipe 

mkfifo schafft eine Named Pipe im Dateisystem. Es sieht aus wie eine Datei, ist aber nicht (wenn Sie einen Blick auf ls -l werfen, werden Sie feststellen, dass der Modus mit beginnt, nicht mit - wie für normale Dateien). Das ist wie das, was foo | bar tut, aber es hat einen Dateinamen und wird von keinem Prozess geöffnet.

Indem Sie dies als Eingabe/Ausgabe an einen Prozess übergeben, können Sie zwei Befehle manuell verbinden (dh ohne Shell-Magie wie |). Daten, die in Pipes geschrieben werden, werden nicht im Dateisystem gespeichert, sind aber für Prozesse verfügbar, die aus der Pipe lesen. Geschriebene Daten werden nur einmal gelesen. Es funktioniert genau wie die Pipes von Shells, außer dass es einen Namen im Dateisystem hat.

+0

Das Standard-Netcat hatte keine '-c' Option. Das traditionelle tut jedoch. Und die Mkifo-Methode verstehe ich nicht wirklich. Ich kannte diesen Befehl nicht, aber es scheint nur eine Datei zu erstellen. – mjgalindo

+0

@MJGalram Ich habe ein paar Zeilen über '' mkfifo'' hinzugefügt. –

+0

Ich endete mit einer Kombination aus Named Pipe und Tee (um die Ausgabe auf dem Bildschirm zu sehen) – mjgalindo

0

Wenn Sie mit C-Servern und Clients arbeiten, kann die folgende Socket-basierte Lösung verwendet werden, um die Daten vom Server zum Client zu übertragen.

Die Lösung verwendet die popen-Funktion zum Ausführen des erforderlichen Befehls auf Ihrem Host-System und übertragen Sie dann die Daten an den Client mit send und recv Primitiven für Socket-Programmierung.

Der Code ist wie folgt:

SERVER:

#include "stdio.h" 
#include "stdlib.h" 
#include "sys/socket.h" 
#include "sys/types.h" 
#include "netinet/in.h" 
#include "error.h" 
#include "string.h" 
#include "unistd.h" 
#include "arpa/inet.h" 

#define ERROR -1 
#define MAX_CLIENTS 2 
#define MAX_DATA 1024 


main(int argc, char **argv) 
{ 
    struct sockaddr_in server; 
    struct sockaddr_in client; 
    int sock; 
    int new,i; 
    int sockaddr_len = sizeof(struct sockaddr_in); 
    int data_len; 
    char data[MAX_DATA]; 
    char temp[MAX_DATA]; 


    if((sock = socket(AF_INET, SOCK_STREAM, 0)) == ERROR) 
    { 
     perror("server socket: "); 
     exit(-1); 
    } 

    server.sin_family = AF_INET; 
    server.sin_port = htons(atoi(argv[1])); 
    server.sin_addr.s_addr = INADDR_ANY; 
    bzero(&server.sin_zero, 8); 

    if((bind(sock, (struct sockaddr *)&server, sockaddr_len)) == ERROR) 
    { 
     perror("bind : "); 
     exit(-1); 
    } 

    if((listen(sock, MAX_CLIENTS)) == ERROR) 
    { 
     perror("listen"); 
     exit(-1); 
    } 
    printf("\nThe TCPServer Waiting for client on port %d\n",ntohs(server.sin_port)); 
     fflush(stdout); 

    FILE *fp; 
    char path[1035]; 

    /* Open the command for reading. */ 
    fp = popen("/bin/ls /etc/", "r"); 

    if((new = accept(sock, (struct sockaddr *)&client, &sockaddr_len)) == ERROR) 
    { 
     perror("accept"); 
     exit(-1); 
    } 

    printf("New Client connected from port no %d and IP %s\n", ntohs(client.sin_port), inet_ntoa(client.sin_addr)); 

    data_len = 1; 

    int path_len; 
    while (fgets(path, sizeof(path)-1, fp) != NULL) { 
     path_len = strlen(path); 
     send(new, path, path_len, 0);  
    } 


    printf("Client disconnected\n"); 

    close(new); 

    close(sock); 


} 

CLIENT:

#include "stdlib.h" 
#include "stdio.h" 
#include "string.h" 
#include "unistd.h" 
#include "sys/socket.h" 
#include "sys/types.h" 
#include "netinet/in.h" 
#include "strings.h" 
#include "arpa/inet.h" 


#define BUFFER 1024 


main(int argc, char **argv) 
{ 
    struct sockaddr_in serv; 
    int sock; 
    char in[BUFFER]; 
    char out[BUFFER]; 
    int len; 


    if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
    { 
     perror("socket"); 
     exit(-1); 
    } 

    serv.sin_family = AF_INET; 
    serv.sin_port = htons(atoi(argv[2])); 
    serv.sin_addr.s_addr = inet_addr(argv[1]); 
    bzero(&serv.sin_zero, 8); 

    printf("\nThe TCPclient %d\n",ntohs(serv.sin_port)); 
     fflush(stdout); 


    if((connect(sock, (struct sockaddr *)&serv, sizeof(struct sockaddr_in))) == -1) 
    { 
     perror("connect"); 
     exit(-1); 
    } 

    len = 1; 
    while(len != 0) { 
     len = recv(sock, out, BUFFER, 0); 
     out[len] = '\0'; 
     printf("Output: %s\n", out); 
    } 

    close(sock); 


} 

Der Servercode die Portnummer als Befehlszeilenargument und dem Client nimmt nimmt die IP-Adresse (127.0.0.1 für localhost) und die Portnummer als Befehlszeilenargumente.

Auch wenn Sie Ihren Server in einer anderen Sprache betreiben, können Sie einfach die Socket-Primitiven für diesen Server verwenden, um Daten an die Client-Datei zu senden.

Hinweis: Der Code wurde in C geschrieben und kann einige Fehler beim Kompilieren mit C++ verursachen. Bitte überprüfen Sie die Kompilierungsfehler.