环境如下: 现运行./server 然后运行./client,在client运行期间用ps -ef | grep server 观看进程信息,有2个进程,等到程序结束后再用同样的命令看,有一个变成了僵尸??但是你再运行一次client的时候僵尸不见了 ,还是2个进程,为什么? 那个不是僵尸??
/*
server.c 要求实现的功能:
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#define PORT 4444
#define BACKLOG 10
#define MAXDATASIZE 4096
int main()
{
int listen_fd,new_fd;
fd_set readfds,writefds;
int ret;
char buf[MAXDATASIZE];
int sin_size;
int numbytes;
struct sockaddr_in their_addr;
struct sockaddr_in my_addr;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
if ((listen_fd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
perror("socket");
exit(1);
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
if(bind(listen_fd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr)) == -1)
{
perror("bind");
exit(1);
}
if (listen(listen_fd,BACKLOG) == -1)
{
}
FD_SET(listen_fd,&readfds);
for(;;)
{
ret = select(listen_fd+1,&readfds,NULL,NULL,NULL);
if(FD_ISSET(listen_fd,&readfds))
{
sin_size =sizeof(struct sockaddr_in);
if((new_fd = accept(listen_fd,(struct sockaddr*)&their_addr,&sin_size)) == -1)
{
perror("accept");
continue;
}
printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));
if (!fork())
{
//先发送一个信息给客户端
if(send(new_fd,"Hello world\n",14,0) == -1)
{
perror("send");
close(new_fd);
exit(0);//这里在子进程里 不能用continue;
}
FD_SET(new_fd,&readfds);
//FD_SET(new_fd,&writefds);
for(;;)
{
ret = select((listen_fd>new_fd?listen_fd+1:new_fd+1),&readfds,NULL,NULL,NULL);
if(FD_ISSET(new_fd,&readfds))
{
if((numbytes=recv(new_fd,buf,MAXDATASIZE,0)) == -1)
{
perror("send");
close(new_fd);
exit(0);//这里在子进程里 不能用continue;
}
if (numbytes > 0)
{
buf[numbytes] = '\0';
printf("Recv: %d\t%s",numbytes,buf);
}
//这里可以使用一个特定的消息作为结束
if (strcmp(buf,"quit\n") == 0)
{
printf("QUIT recved!\n");
FD_CLR(new_fd,&readfds);
close(new_fd);
//exit(0); 这里如果用exit那么就会产生僵尸???
return 0;
//break;
}
//再向客户端发送一条信息
if (send(new_fd,"A new string\n",14,0) == -1)
{
perror("send");
close(new_fd);
exit(0);//这里在子进程里 不能用continue
}
else
printf("Msg Send!\n");
}
}
}
}
//等待所有子进程退出
while(waitpid(-1,NULL,WNOHANG)>0);
printf("Father Flushed!\n");
//return 0;
}
return 0;
}
/*
client.c 要求实现的功能:每秒向server发送一个消息
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#define PORT 4444
#define BACKLOG 10
#define MAXDATASIZE 4096
int main()
{
int sock_fd,numbytes;
char buf[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr;
int ret;
fd_set readfds;
int cnt = 0;
char* strIP="20.0.0.5";
FD_ZERO(&readfds);
if ((he = gethostbyname(strIP)) == NULL)
{
perror("gethostbyname");
exit(1);
}
if ((sock_fd=socket(AF_INET,SOCK_STREAM,0)) == -1)
{
perror("socket");
exit(1);
}
their_addr.sin_family =AF_INET;
their_addr.sin_port =htons(PORT);
their_addr.sin_addr = *((struct in_addr*)he->h_addr);
bzero(&(their_addr.sin_zero),8);
if (connect(sock_fd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) == -1)
{
perror("connect");
exit(1);
}
if ((numbytes = recv(sock_fd,buf,MAXDATASIZE,0)) == -1)
{
perror("recv");
exit(1);
}
if(numbytes > 0)
{
buf[numbytes] = '\0';
printf("Recv:%s",buf);
}
while(cnt++ < 10)
{
sleep(1);
if(send(sock_fd,"subsentence\n",13,0) == -1)
{
perror("send");
close(sock_fd);
exit(0);//这里在子进程里 不能用continue;
}
FD_SET(sock_fd,&readfds);
ret = select(sock_fd+1,&readfds,NULL,NULL,NULL);
if(FD_ISSET(sock_fd,&readfds))
{
if ((numbytes = recv(sock_fd,buf,MAXDATASIZE,0)) == -1)
{
perror("recv");
exit(1);
}
if(numbytes > 0)
{
buf[numbytes] = '\0';
printf("Recv:%s",buf);
}
}
}
if(send(sock_fd,"quit\n",5,0) == -1)
{
perror("send");
close(sock_fd);
exit(0);//这里在子进程里 不能用continue;
}
close(sock_fd);
return 0;
}