的请forkLinux 网络编程之 socket 使用 fork 并发处理多个 client
的请
fork
求和对等通信 P2P
、如何同时服务多个客户端呢?在未讲到
select/poll/epoll 等高级 IO 之前, 比较老土的办法是使用 来实现。网络服务器通常用 fork 来同时服务多个客户端, 进程专门负责监听端口,每次 accept 一个新的客户端连接就
fork 出一个子进程专门服务这个客户端。但是子进程退出时 会产生僵尸进程,父进程要注意处理 SIGCHLD 信号和调用
wait 清理僵尸进程,最简单的办法就是直接忽略 SIGCHLD
信号。
面为服务器端程序 :
#include #include #include #include #include #include #include #include #include
#include
#define ERR_EXIT(m)do {perror(m);exit(EXIT_FAILURE);
#define ERR_EXIT(m)
do {
perror(m);
exit(EXIT_FAILURE);
} while (0)
void do_service(int);
int main(void)
signal(SIGCHLD, SIG_IGN);
int listenfd; // 被动套接字 (文件描述符) ,即只可以 accept,
监听套接字
if ((listenfd = socket(PF_INET, SOCK_STREAM,
IPPROTO_TCP)) < 0)
// listenfd = socket(AF_INET, SOCK_STREAM, 0)
ERR_EXIT("socket error");
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(5188);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
/* servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); */ /* inet_aton("127.0.0.1", &servaddr.sin_addr); */ int on = 1;
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,
&on, sizeof(on)) < 0)
ERR_EXIT("setsockopt error");
if (bind(listenfd, (struct sockaddr *)&servaddr,
sizeof(servaddr)) < 0)
ERR_EXIT("bind error");
if (listen(listenfd, SOMAXCONN) < 0) //listen应在 socket
和 bind 之后,而在 accept 之前
ERR_EXIT("listen error");
struct sockaddr_in peeraddr; // 传出参数
socklen_t peerlen = sizeof(peeraddr); // 传入传出参数,必
须有初始值
int conn; // 已连接套接字 (变为主动套接字, 即可以主动
connect)
pid_t pid;
while (1)
if ((conn = accept(listenfd, (struct sockaddr
*)&peeraddr, &peerlen)) < 0) //3 次握手完成的序列
ERR_EXIT("accept error");
printf("recv connect ip=%s port=%d\n",
inet_ntoa(peeraddr.sin_addr),
ntohs(peeraddr.sin_port));
pid = fork();
if (pid == -1)
ERR_EXIT("fork error");
if (pid == 0)
// 子进程
close(listenfd);
do_service(conn);
exit(EXIT_SUCCESS);
else
close(conn); // 父进程
return 0;
void do_service(int conn)
char recvbuf[1024];
while (1)
memset(recvbuf, 0, sizeof(recvbuf));
int ret = read(