将程序 A 的输出重定向到程序 B 的输入,反之亦然
Redirect output from program A to program B's input and viceversa
我知道有一种方法可以通过使用 fork 并以某种方式制作管道在 C 中对此进行编程(我知道有一种方法,但我不记得如何去做)。
预期用途是将服务器的输出(我将使用 netcat 获得)连接到我自己的 c++ 程序,该程序将处理所述输出并将其归还给 netcat。我不知道如何在 C++ 中直接连接(套接字是神秘的生物),我想避免安装 boost,因为它应该在或多或少的香草系统中编译。
那么,有没有一种方法可以使用 bash 将一个程序的输出重定向到另一个程序的输入,并将第二个程序的输出重定向到 bash 中第一个程序的输入?
给定一个 netcat 实现,您已经拥有了所需的东西。假设您的客户端名为 /path/to/client
,您希望在端口 1234 连接到 service.example.com
。
要么你的 netcat 就像 nmap 中的 ncat,那么你可以这样做:
ncat -c ``/path/to/client`` service.example.com 1234
如果你的 netcat 更简约,你必须使用管道:
mkdir pipes
cd pipes
mkfifo reverse_pipe
/path/to/client < reverse_pipe | nc service.example.com 1234 > reverse_pipe
mkfifo
在文件系统中创建命名管道。它看起来像一个文件,但实际上不是(如果您使用 ls -l
查看它,您会注意到它的模式以 p
开头,而不是像普通文件那样以 -
开头)。这就像 foo | bar
所做的,但它有一个文件名,并且不被任何进程打开。
通过将其作为 input/output 传递给进程,您可以手动连接两个命令(即,没有 shell 魔术,例如 |
)。写入管道的数据不存储在文件系统中,但可用于从管道读取的进程。写入的数据只会被读取一次。它的工作方式与 shells 中的管道完全一样,只是它在文件系统中有一个名称。
如果您正在使用 C 风格的服务器和客户端,则可以使用以下基于套接字的解决方案将数据从服务器传输到客户端。
该解决方案使用 popen
函数来执行主机系统上的 运行 所需命令,然后使用 send
和 recv
原语将数据传输到客户端套接字编程。
代码如下:
服务器:
#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);
}
客户:
#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] = '[=11=]';
printf("Output: %s\n", out);
}
close(sock);
}
服务器代码将端口号作为命令行参数,客户端将 ip 地址(本地主机为 127.0.0.1)和端口号作为命令行参数。
即使您是 运行 使用其他语言的服务器,您也可以简单地使用该服务器的套接字原语将数据发送到客户端文件。
注意:代码是用C语言编写的,用C++编译时可能会产生一些错误。请检查编译错误。
我知道有一种方法可以通过使用 fork 并以某种方式制作管道在 C 中对此进行编程(我知道有一种方法,但我不记得如何去做)。
预期用途是将服务器的输出(我将使用 netcat 获得)连接到我自己的 c++ 程序,该程序将处理所述输出并将其归还给 netcat。我不知道如何在 C++ 中直接连接(套接字是神秘的生物),我想避免安装 boost,因为它应该在或多或少的香草系统中编译。
那么,有没有一种方法可以使用 bash 将一个程序的输出重定向到另一个程序的输入,并将第二个程序的输出重定向到 bash 中第一个程序的输入?
给定一个 netcat 实现,您已经拥有了所需的东西。假设您的客户端名为 /path/to/client
,您希望在端口 1234 连接到 service.example.com
。
要么你的 netcat 就像 nmap 中的 ncat,那么你可以这样做:
ncat -c ``/path/to/client`` service.example.com 1234
如果你的 netcat 更简约,你必须使用管道:
mkdir pipes
cd pipes
mkfifo reverse_pipe
/path/to/client < reverse_pipe | nc service.example.com 1234 > reverse_pipe
mkfifo
在文件系统中创建命名管道。它看起来像一个文件,但实际上不是(如果您使用 ls -l
查看它,您会注意到它的模式以 p
开头,而不是像普通文件那样以 -
开头)。这就像 foo | bar
所做的,但它有一个文件名,并且不被任何进程打开。
通过将其作为 input/output 传递给进程,您可以手动连接两个命令(即,没有 shell 魔术,例如 |
)。写入管道的数据不存储在文件系统中,但可用于从管道读取的进程。写入的数据只会被读取一次。它的工作方式与 shells 中的管道完全一样,只是它在文件系统中有一个名称。
如果您正在使用 C 风格的服务器和客户端,则可以使用以下基于套接字的解决方案将数据从服务器传输到客户端。
该解决方案使用 popen
函数来执行主机系统上的 运行 所需命令,然后使用 send
和 recv
原语将数据传输到客户端套接字编程。
代码如下:
服务器:
#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);
}
客户:
#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] = '[=11=]';
printf("Output: %s\n", out);
}
close(sock);
}
服务器代码将端口号作为命令行参数,客户端将 ip 地址(本地主机为 127.0.0.1)和端口号作为命令行参数。
即使您是 运行 使用其他语言的服务器,您也可以简单地使用该服务器的套接字原语将数据发送到客户端文件。
注意:代码是用C语言编写的,用C++编译时可能会产生一些错误。请检查编译错误。