Linux 父进程监听套接字到子进程继承
在 Linux 中,当父进程创建了一个监听套接字并绑定了一个端口,然后 fork 一个子进程,子进程需要继承父进程的监听套接字并继续监听。这可以通过以下步骤实现:
- 父进程创建监听套接字并绑定端口。
- 父进程 fork 出子进程。
- 子进程关闭父进程的监听套接字。
- 子进程重新创建一个新的监听套接字并绑定到相同的端口。
- 子进程开始监听新的套接字。
以下是示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
int listen_fd, conn_fd;
struct sockaddr_in serv_addr, cli_addr;
socklen_t cli_len;
pid_t pid;
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) {
perror("socket error");
exit(EXIT_FAILURE);
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(8080);
if (bind(listen_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
perror("bind error");
exit(EXIT_FAILURE);
}
if (listen(listen_fd, 10) < 0) {
perror("listen error");
exit(EXIT_FAILURE);
}
while (1) {
cli_len = sizeof(cli_addr);
conn_fd = accept(listen_fd, (struct sockaddr*)&cli_addr, &cli_len);
if (conn_fd < 0) {
perror("accept error");
exit(EXIT_FAILURE);
}
pid = fork();
if (pid < 0) {
perror("fork error");
exit(EXIT_FAILURE);
} else if (pid == 0) {
close(listen_fd); // 关闭父进程的监听套接字
// 子进程重新创建一个新的监听套接字并绑定到相同的端口
int new_listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (new_listen_fd < 0) {
perror("socket error");
exit(EXIT_FAILURE);
}
if (bind(new_listen_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
perror("bind error");
exit(EXIT_FAILURE);
}
if (listen(new_listen_fd, 10) < 0) {
perror("listen error");
exit(EXIT_FAILURE);
}
// 子进程开始监听新的套接字
while (1) {
cli_len = sizeof(cli_addr);
conn_fd = accept(new_listen_fd, (struct sockaddr*)&cli_addr, &cli_len);
if (conn_fd < 0) {
perror("accept error");
exit(EXIT_FAILURE);
}
// 处理客户端连接
char buf[1024];
int n = read(conn_fd, buf, sizeof(buf));
if (n < 0) {
perror("read error");
exit(EXIT_FAILURE);
} else if (n == 0) {
close(conn_fd);
break;
} else {
write(conn_fd, buf, n);
}
close(conn_fd);
}
close(new_listen_fd);
exit(EXIT_SUCCESS);
} else {
close(conn_fd);
}
}
close(listen_fd);
return 0;
}
原文地址: http://www.cveoy.top/t/topic/kTu0 著作权归作者所有。请勿转载和采集!