服务器linux内核版本是:2.6.32。服务器创建3个子进程同时监听一个端口,客户端发送请求,只有一个子进程去相应,accept并没有出现网上说的惊群现象。
#include <stdio.h>
#include <sys/types.h>#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void* Signal(int signo, void* handler)
{
struct sigaction act, oact;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if(signo == SIGALRM)
{
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
}else{
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART;
#endif
}
if(sigaction(signo, &act, &oact)<0)
{
return SIG_ERR;
}
return oact.sa_handler;
}
int main(int argc, char *argv[])
{
int sockfd;
int newsockfd;
unsigned int clilen;
char buffer[2560];
struct sockaddr_in serv_addr;
struct sockaddr_in cli_addr;
int n;
int flags=0;
int i=0;
pid_t fpid;
#ifdef SIGCLD
Signal(SIGCLD,SIG_IGN);
#endif
#ifdef SIGCHLD
Signal(SIGCHLD, SIG_IGN);
#endif
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
printf("opening socket error! \n");
exit(-1);
}
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(6578);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
printf("socket binding error! \n");
exit(-1);
}
listen(sockfd, 100);
while(i++<3)
{
fpid=fork();
if (fpid < 0)
printf("error in fork!\n");
else if(fpid==0)
{
printf("fork ==[%d]== child\n", i);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
{
printf("accept error! \n");
exit(-1);
}
printf("pid=[%d],accept one connect\n",getpid());
n = read(newsockfd, buffer, sizeof(buffer));
if (n < 0)
printf("pid=[%d]error reading from socket! \n",getpid());
else
printf("pid=[%d]here is the message=== [%s] \n", getpid(),buffer);
sleep(60);
write()
close(sockfd);
close(newsockfd);
exit(0);
}
else
{
printf("pid=[%d]father program! \n",getpid());
}
}
return 0;
}