#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
void recyle(int num){
pid_t pid;
while((pid = waitpid(-1, NULL, WNOHANG)) > 0){
printf("child is died! it's pid = %d\n", pid);
}
}
int main(int argc, char **argv)
{
if(argc != 3){
printf("parameter error!\n");
exit(-1);
}
int sockfd;
int c_fd;
pid_t pid;
char readbuf[128] = {0};
char writebuf[128] = {0};
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
memset(&s_addr, 0, sizeof(s_addr));
memset(&c_addr, 0, sizeof(c_addr));
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1){
perror("socket");
exit(-1);
}
//使用信号回收子进程的PCB
struct sigaction act;
act.sa_handler = recyle;
act.sa_flags = 0;
sigemptyset(&act.sa_mask); //屏蔽不想要的信号,这里什么也不屏蔽。
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1], &s_addr.sin_addr);
if(bind(sockfd, (struct sockaddr *)&s_addr, sizeof(s_addr)) == -1){
perror("bind");
exit(-1);
}
listen(sockfd, 20);
printf("正在等待连接......\n");
int len = sizeof(struct sockaddr_in);
int nread;
int i = 0;
while(1){
c_fd = accept(sockfd, (struct sockaddr*)&c_addr, &len);
i++;
while(c_fd == -1 && errno == EINTR){
c_fd = accept(sockfd, (struct sockaddr*)&c_addr, &len);
}
if(c_fd != -1){
printf("Welcome client[%d]:%s,port:%d\n", i, inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port));
pid = fork();
if(pid == 0){
// child
close(sockfd);
while(1){
pid_t pid1;
pid1 = fork();
if(pid1 > 0){
memset(readbuf, 0, sizeof(readbuf));
nread = read(c_fd, readbuf, sizeof(readbuf));
if(nread < 0){
perror("read");
exit(-1);
}else if(nread == 0){
printf("客户端已断开连接!\n");
close(c_fd);
break;
}else{
printf("recv %d byte: %s", nread, readbuf);
}
}else if(pid1 == 0){
memset(writebuf, 0, sizeof(writebuf));
fgets(writebuf, sizeof(writebuf), stdin);
write(c_fd, writebuf, strlen(writebuf));
}else{
perror("fork1");
exit(-1);
}
}
exit(1);
}
else if(pid < 0){
perror("fork");
exit(-1);
}else{
//father
close(c_fd);
}
}
}
return 0;
}