fork并发服务器

本文介绍了一个基于fork的并发服务器的设计与实现过程。该服务器能够处理客户端连接请求,并通过子进程来响应不同的客户端操作,如文件目录的列出等功能。文章详细展示了如何使用C语言和系统调用完成这一目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

//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);

}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值