16、并发服务器

 

              UDP并发服务器

              UDP循环服务器实现的方法:

              UDP服务器每次从套接字上读取一个客户端的请求,接着处理,然后将结果返回给客户机。

              socket();

              bind();

              while(1)

              {

                     recvfrom();

                     process();

                     sendto();

              }

 

                                   TCP循环服务器

              TCP循环服务器接受一个客户端的连接,然后处理,完成了这个客户的所有请求后,断开连接:

                     socket();

                     bind();

                     listen();

                     while(1)

                            {

                                   accept();

                                   process();

                                   close();

                            }

 

              TCP循环服务器一次只能处理一个客户端的请求。只有在这个客户端的所有请求都满足后,服务器才可以继续后面的请求。这样如果有一个客户端占住服务器不放时,其他的客户机都不能工作了,因此,TCP服务器一般很少用循环 服务器模型

 

                                   TCP并发服务器(循环服务器改造的)

              并发服务器的思想是每一个客户机的请求并不由服务器直接处理,而是由服务器创建一个子进程来处理

              socket();

              bind();

              listen();

              while(1)

                     {

                            accept();

                            if(fork()==0)

                            {

                                   process();

                                   close();

                                   exit();

                                   }

                                   close();

                     }

 

 

 

                     例题:TCP并发服务器、

                                                

                                  Tcp_server_fork.c

#include <stdlib.h>

#include <stdio.h>

#include <errno.h>

#include <string.h>

#include <netdb.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

 

#define MY_PORT 3333

 

int main(int argc ,char **argv)

{

 int listen_fd,accept_fd;

 struct sockaddr_in     client_addr;

 int n;

 

 if((listen_fd=socket(AF_INET,SOCK_STREAM,0))<0)

  {

        printf("Socket Error:%s\n\a",strerror(errno));

        exit(1);

  }

 

 bzero(&client_addr,sizeof(struct sockaddr_in));

 client_addr.sin_family=AF_INET;

 client_addr.sin_port=htons(MY_PORT);

 client_addr.sin_addr.s_addr=htonl(INADDR_ANY);

 n=1;

 /* 如果服务器终止后,服务器可以第二次快速启动而不用等待一段时间  */

 setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(int));

 if(bind(listen_fd,(struct sockaddr *)&client_addr,sizeof(client_addr))<0)

  {

        printf("Bind Error:%s\n\a",strerror(errno));

        exit(1);

  }

  listen(listen_fd,5);

  while(1)

  {

   accept_fd=accept(listen_fd,NULL,NULL);

   if((accept_fd<0)&&(errno==EINTR))

          continue;

   else if(accept_fd<0)

    {

        printf("Accept Error:%s\n\a",strerror(errno));

        continue;

    }

  if((n=fork())==0)

   {

        /* 子进程处理客户端的连接 */

        char buffer[1024];

 

        close(listen_fd);

        n=read(accept_fd,buffer,1024);

        write(accept_fd,buffer,n);

        close(accept_fd);

        exit(0);

   }

   else if(n<0)

        printf("Fork Error:%s\n\a",strerror(errno));

   close(accept_fd);

  }

}

 

 

 

 

 

                                                 Tcp_client.c

#include <stdlib.h>

#include <stdio.h>

#include <errno.h>

#include <string.h>

#include <netdb.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

 

#define portnumber 3333

 

int main(int argc, char *argv[])

{

    int sockfd;

    char buffer[1024];

    struct sockaddr_in server_addr;

    struct hostent *host;

 

        /* 使用hostname查询host 名字 */

    if(argc!=2)

    {

        fprintf(stderr,"Usage:%s hostname \a\n",argv[0]);

        exit(1);

    }

 

    if((host=gethostbyname(argv[1]))==NULL)

    {

        fprintf(stderr,"Gethostname error\n");

        exit(1);

    }

 

    /* 客户程序开始建立 sockfd描述符 */

    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) // AF_INET:Internet;SOCK_STREAM:TCP

    {

        fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));

        exit(1);

    }

 

    /* 客户程序填充服务端的资料 */

    bzero(&server_addr,sizeof(server_addr)); // 初始化,置0

    server_addr.sin_family=AF_INET;          // IPV4

    server_addr.sin_port=htons(portnumber);  // (将本机器上的short数据转化为网络上的short数据)端口号

    server_addr.sin_addr=*((struct in_addr *)host->h_addr); // IP地址

   

    /* 客户程序发起连接请求 */

    if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)

    {

        fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));

        exit(1);

    }

 

    /* 连接成功了 */

    printf("Please input char:\n");

   

    /* 发送数据 */

    fgets(buffer,1024,stdin);

    write(sockfd,buffer,strlen(buffer));

 

    /* 结束通讯 */

    close(sockfd);

    exit(0);

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值