多进程模型
多进程模型下,注意如何在进程之间通信以及孤儿进程和僵尸进程的处理,可以外配上进程池作为计算任务/异步任务的处理。
//fork server
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <signal.h>
void run();
int main(int argc, char *argv[])
{
run();
return 0;
}
void handle_client_socket(int clientfd){
//read from client socket
char readbuf[1024];
ssize_t readlen;
while(1){
readlen = read(clientfd, readbuf, sizeof(readbuf));
if (readlen==-1){
perror("read client error");
close(clientfd);
return;
}else if(readlen==0){
break;
}else{
fwrite(readbuf, readlen, 1, stdout);
//write back to client
if(write(clientfd, readbuf, readlen)==-1){
perror("write back to client error");
close(clientfd);
return;
}
}
}
close(clientfd);
}
void reap(int signum)
{
while(waitpid(-1, NULL, WNOHANG)>0);
return;
}
void run()
{
//get hostent
struct hostent *h = gethostbyname("127.0.0.1");
if(!h){
perror("resolve host failed");
exit(EXIT_FAILURE);
}
//create server socket
int fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd==-1){
perror("socket create failed");
exit(EXIT_FAILURE);
}
//server bind
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr = *(struct in_addr *)h->h_addr_list[0];
server.sin_port = htons(8000);
if(bind(fd, (struct sockaddr *)&server, sizeof(server))==-1){
perror("bind error");
close(fd);
exit(EXIT_FAILURE);
}
int reuse = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))<0){
perror("error setsockopt");
exit(EXIT_FAILURE);
}
//server listen
if(listen(fd,20)==-1){
perror("listen error");
close(fd);
exit(EXIT_FAILURE);
}
signal(SIGCHLD,reap);
//server loop
while(1){
//struct sockaddr_in client;
struct sockaddr_storage client;
int clientfd;
socklen_t socklen = sizeof(client);
clientfd = accept(fd, (struct sockaddr *)&client, &socklen);
if (clientfd==-1){
perror("error accept");
close(fd);
exit(EXIT_FAILURE);
}
pid_t pid = fork();
if(pid==-1){
perror("fork error");
close(fd);
exit(EXIT_FAILURE);
}
if (pid==0){
//close parent listening fd
close(fd);
handle_client_socket(clientfd);
exit(EXIT_SUCCESS);
}
if (pid>0){
//close client fd
close(clientfd);
}
}
}