要编写一个能够复制 Linux 上某个端口的流量并将其转发到另一台服务器的 C 代码,你可以使用套接字编程来实现。以下是一个简单的示例,演示如何在 Linux 中编写这样的代码。请注意,这是一个基本示例,实际情况可能需要更多的错误处理和功能。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUFFER_SIZE 1024
int main(int argc, char *argv[]) {
if (argc != 4) {
fprintf(stderr, "Usage: %s <listen-port> <forward-ip> <forward-port>\n", argv[0]);
exit(1);
}
int listen_port = atoi(argv[1]);
char *forward_ip = argv[2];
int forward_port = atoi(argv[3]);
// 创建监听套接字
int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if (listen_sock == -1) {
perror("socket");
exit(1);
}
// 绑定监听套接字到指定端口
struct sockaddr_in listen_addr;
memset(&listen_addr, 0, sizeof(listen_addr));
listen_addr.sin_family = AF_INET;
listen_addr.sin_addr.s_addr = INADDR_ANY;
listen_addr.sin_port = htons(listen_port);
if (bind(listen_sock, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) == -1) {
perror("bind");
close(listen_sock);
exit(1);
}
// 监听连接
if (listen(listen_sock, 10) == -1) {
perror("listen");
close(listen_sock);
exit(1);
}
printf("Listening on port %d...\n", listen_port);
// 创建转发套接字
int forward_sock = socket(AF_INET, SOCK_STREAM, 0);
if (forward_sock == -1) {
perror("socket");
close(listen_sock);
exit(1);
}
// 连接到目标服务器
struct sockaddr_in forward_addr;
memset(&forward_addr, 0, sizeof(forward_addr));
forward_addr.sin_family = AF_INET;
forward_addr.sin_port = htons(forward_port);
if (inet_pton(AF_INET, forward_ip, &forward_addr.sin_addr) <= 0) {
perror("inet_pton");
close(listen_sock);
close(forward_sock);
exit(1);
}
if (connect(forward_sock, (struct sockaddr *)&forward_addr, sizeof(forward_addr)) == -1) {
perror("connect");
close(listen_sock);
close(forward_sock);
exit(1);
}
printf("Forwarding traffic to %s:%d...\n", forward_ip, forward_port);
// 开始接受连接并转发数据
while (1) {
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
int client_sock = accept(listen_sock, (struct sockaddr *)&client_addr, &addr_len);
if (client_sock == -1) {
perror("accept");
close(listen_sock);
close(forward_sock);
exit(1);
}
// 创建一个子进程来处理连接
pid_t pid = fork();
if (pid == -1) {
perror("fork");
close(client_sock);
} else if (pid == 0) { // 子进程
close(listen_sock);
// 转发数据
char buffer[BUFFER_SIZE];
ssize_t bytes_read;
while ((bytes_read = read(client_sock, buffer, sizeof(buffer))) > 0) {
write(forward_sock, buffer, bytes_read);
}
// 关闭套接字
close(client_sock);
close(forward_sock);
exit(0);
} else { // 父进程
close(client_sock);
}
}
return 0;
}
这段代码创建了一个监听套接字来接受客户端连接,并创建了一个转发套接字来连接到目标服务器。然后,它使用 fork
创建子进程来处理每个连接,从客户端读取数据并将其写入目标服务器,实现了流量的复制和转发。
请注意,这只是一个简单的示例,没有包括所有可能的错误处理和边界情况。在实际应用中,你可能需要更多的安全性和稳定性措施。此外,这个示例是单线程的,如果需要更高的性能,可以考虑使用多线程或异步编程。