//fork 并发服务器
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <dirent.h>
#include <string.h>
#include <signal.h>
#define N 64
int cmd_act(char *cmd_buf,int connfd)
{
DIR *dirptr=NULL;
struct dirent *filenameptr=NULL;
char buf[N];
int n;
if(strncmp(cmd_buf,"ls",2)==0)
{
if((dirptr=opendir("."))!=NULL)
{
while((filenameptr=readdir(dirptr))!=NULL)
{
strcpy(buf,filenameptr->d_name);
n=strlen(buf);
buf[n]='\n';
send(connfd, buf, n+1, 0);
}
}
}
return 1;
}
void hander_signal(int sig)
{
int state;
pid_t pid;
// if(sig==SIGCHLD)
//僵尸进程回收
while((pid=waitpid(-1,0,WNOHANG)>0))
{
printf("terminale %d \n",pid);
}
// wait(&state);
}
int main(int argc, char *argv[])
{
//./server 192.168.1.240 9000
int sockfd, connfd;
struct sockaddr_in myaddr, peeraddr;
socklen_t len;
char buf[N] = {0};
ssize_t n;
//fork id
int fid;
int *state;
if (argc < 3)
{
printf("usage:%s ip port\n", argv[0]);
exit(0);
}
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(-1);
}
bzero(&myaddr, sizeof(myaddr));
myaddr.sin_family = PF_INET;
myaddr.sin_port=htons(atoi(argv[2]));//htons(6000)
myaddr.sin_addr.s_addr=inet_addr(argv[1]);
if (bind(sockfd,(struct sockaddr *)&myaddr, sizeof(myaddr)) == -1)
{
perror("bind");
exit(-1);
}
if (listen(sockfd, 5) == -1)
{
perror("listen");
exit(-1);
}
bzero(&peeraddr, sizeof(peeraddr));
len = sizeof(peeraddr);
signal(SIGCHLD,hander_signal);
while (1)
{
if ((connfd = accept(sockfd, (struct sockaddr *)&peeraddr, &len)) == -1)
{
perror("accept");
exit(-1);
}
printf("welcome from %s :%d\n", inet_ntoa(peeraddr.sin_addr),
ntohs(peeraddr.sin_port));
#if 0
while (1)
{
bzero(buf, sizeof(buf));
n = recv(connfd, buf, N, 0);
if (n == 0)
break;
buf[n] = 0;
printf("n = %d: %s\n", n, buf);
send(connfd, buf, n, 0);
//cmd_act(buf,connfd);
}
#endif
if((fid=fork())<0)
{
perror("creat thread error...");
exit(-1);
}
if(fid==0)
{
//核心代码:有新的的客户端连接服务器端时间子进程被创建响应客户端
close(sockfd);//关闭和自己无关的文件描述符
while(1)
{
bzero(buf, sizeof(buf));
n = recv(connfd, buf, N, 0);
if (n == 0)
break;
buf[n] = 0;
printf("n = %d: %s\n", n, buf);
send(connfd, buf, n, 0);
}
close(connfd); //当客户端退出后,关闭子进程的服务器的描述符
exit(1);//子进程退出 这时子进程形成僵尸进程 回收僵尸进程
}
if(fid>0)
{
//signal(SIGCHLD,hander_signal);
close(connfd);
//exit(1);
}
}
exit(0);
}