#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUFF_SIZE 1024
//错误输出
void error_handing(char*message)
{
fputs(message, stderr);
exit(1);
}
//信号处理函数,读取子进程进程号
void read_childproc(int sig)
{
pid_t pid;
int status;
pid = waitpid(-1, &status,WNOHANG);
printf("removed proc id is : %d\n", pid);
}
int main()
{
//初始化信号和相关变量即buff
char buff[BUFF_SIZE];
pid_t pid;
struct sigaction act;
act.sa_handler = read_childproc;//绑定信号处理函数
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGCHLD, &act, 0);//绑定信号SIGCHLD(子进程状态改变信号)和处理函数read_childproc
uint16_t port;
//1、创建服务器套接字
int ser_socket = socket(PF_INET, SOCK_STREAM, 0);
//2、绑定服务器信息
struct sockaddr_in ser_addr;
memset(&ser_addr, 0, sizeof(ser_addr));
ser_addr.sin_family = AF_INET;
ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
ser_addr.sin_port = htons(port);
int ser_addrLen = sizeof(ser_addr);
if(bind(ser_socket, (struct sockaddr*)&ser_addr, sizeof(ser_addr)) == -1)
{
error_handing("bind() error");
}
//3、监听客户端连接, 5个
if(listen(ser_socket, 5) == -1)
{
error_handing("listen() error");
}
//4、初始化客户端相关信息
int cli_socket;
struct sockaddr_in cli_addr;
memset(&cli_addr, 0, sizeof(cli_addr));
int cli_addrLen = sizeof(cli_addr);
//5、处理连接和创建子进程
while(1)
{
cli_socket = accept(ser_socket, (struct sockaddr*)&cli_addr, &cli_addrLen);
if(cli_socket == -1)
{
continue;
}
else{
printf("new client connected\n");
}
//6、为新连接客户端创建子进程
pid = fork();
if(pid == -1)//进程创建失败
{
close(cli_socket);
continue;
}
else if(pid == 0)//子进程运行区域
{
close(ser_socket);
while(read(cli_socket, buff, BUFF_SIZE) != 0)
{
char*buf = "I am SERVER";
write(cli_socket, buf, sizeof(buf));
}
close(cli_socket);
puts("client disconnected>>>>");
return 0;
}
else
close(cli_socket);
}
close(ser_socket);
return 0;
}