具有多个客户端的套接字服务器.杀死子进程
Socket Server with Multiple clients. Killing child processes
我一直在编写一个应该使用 fork() 与多个客户端一起工作的服务器。我正在关闭套接字并退出子进程,但在处理所有客户端后,我最终得到了大量的子进程(已使用 ps -ef 检查过)。
我在这里错过了什么吗?
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "sbb_socket.h"
#include "bond_container.h"
#include <iostream>
#define SBB_ANY
void do_process(int sd_current);
int main(int argc, char* argv[])
{
/*
* get the number of clients from argument
*/
long client_count = 1;
if (argc > 1 && strtol(argv[1], NULL, 10) > 0) {
client_count = strtol(argv[1], NULL, 10);
}
pid_t pid;
int sd_current;
/*
* get an internet domain socket
*/
int sd;
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
/*
* set up the socket structure
*/
struct sockaddr_in sock_addr;
memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
#ifdef SBB_ANY
/* set to INADDR_ANY if want server to be open to any client on any machine */
sock_addr.sin_addr.s_addr = INADDR_ANY;
#else
char hostname[128];
/*
* we'll default to this host and call a section 3 func to get this host
*/
if( gethostname(hostname,sizeof(hostname)) ){
fprintf(stderr," SBB gethostname(...) failed errno: %dn", errno);
exit(1);
}
//printf("SBB gethostname() local hostname: "%s"n", hostname);
/*
* set up socket structure for our host machine
*/
struct hostent *hp;
if ((hp = gethostbyname(hostname)) == 0) {
fprintf(stderr,"SBB gethostbyname(...) failed errno: %d exiting...n", errno);
exit(1);
}
sock_addr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
#endif
sock_addr.sin_port = htons(PORT);
/*
* bind the socket to the port number
*/
if (bind(sd, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) == -1) {
perror("bind");
exit(1);
}
/*
* advertise we are available on this socket/port
*/
if (listen(sd, 5) == -1) {
perror("listen");
exit(1);
}
while(1)
{
/*
* wait for a client to connect
*/
struct sockaddr_in sock_addr_from_client;
socklen_t addrlen = sizeof(sock_addr_from_client);
if ((sd_current = accept(sd, (struct sockaddr *) &sock_addr_from_client, &addrlen)) == -1) {
fprintf(stderr,"SBB accept(...) failed errno: %d exiting...n", errno);
exit(1);
}
/*
* block on socket waiting for client message
*/
if ((pid = fork()) < 0) {
printf("Error on fork");
exit(1);
}
if (pid == 0) {
close(sd);
do_process(sd_current);
exit(0);
}
else {
close(sd_current);
}
}
}
挂起的子进程可能是僵尸进程。例如,您可以执行以下操作以避免出现问题:
- 在父进程中使用
wait()
waitpid()
来摆脱僵尸。 - 使用"双分叉"技巧将子进程置于初始化进程下。
相关文章:
- 终止 QProcess 不会终止子进程
- 什么时候最好在子进程中使用 CPU 或 I/O 密集型代码 [ C++ ]
- 子进程更新共享 mmap 内存,但父进程没有更改
- 使用 waitpid 时等待子进程终止
- 使用重定向标准处理子进程中的 kbhit
- 由 JOB 中的进程启动的子进程是否可以将 JOB 属性设置为脱离作业?
- 是否可以将子进程的 stdout 重定向到父进程中的另一个文件?
- kill() 总是返回 0(成功),即使在子进程已经结束之后?
- 父进程和子进程之间的 POSIX 信号量
- 检测到由于操作系统内存不足而导致子进程终止
- 使用system()创建独立的子进程
- 从stdin读取时子进程挂起(fork/dup2竞争条件)
- 在 Bash 脚本中处理来自子进程的信号
- Qt C++ - 如何成功将数据传递给子进程?
- C++ 窗口本地系统模拟在子进程中失败
- 将类型化数组写入子进程 stdin 无法正常工作
- 将 nodejs 脚本作为子进程执行(而不是从其他脚本执行)
- 使用信号检测子进程何时终止的最佳方法是什么?
- 具有多个客户端的套接字服务器.杀死子进程
- ZeroMQ与分叉服务器中的所有子进程共享上下文