• 第三季-第26课-网络并发服务器设计


    第26课-网络并发服务器设计

    26.1 问题描述

    在我们第24节课操作的内容中。是有一个服务器和一个客户端的条件。但是在生活中,我们会遇到多个客户端的情况。我们先在linux系统上做一下模拟操作,在一个终端运行./tcp_server,在另外两个终端分别运行./tcp_client程序。我们会发现客户端对第一个运行的程序响应后就不会对另一个响应,直到第一个运行结束,然后才会运行第二个。这种情况也叫循环服务器。这样的服务器处理的效率是非常低的。

    26.2 解决办法

    为了解决上面的问题,我们引入并发服务器,并发也就是能够同时处理的意思。可以采用的方法很多(多进程,多线程等),今天我们采用多进程的方法。

    编程实现并发服务器。我们先看一下,以前我们编的程序的运行步骤:(1)创建套接字(2)绑定套接字(3)循环:建立连接,数据处理(4)结束。问题就出现在第三步上,当我们进行数据处理的时候,若没有处理完数据就会一直等待,然后才会去建立新的连接。为了解决这一个问题,我们可以建立子进程,让子进程去处理数据,父进程就可以一直处于建立连接的过程。每建立一个连接,就把它交给一个子进程。这样就提高了效率。

    tcp_server_fork.c

    #include<sys/socket.h>

    #include<stdio.h>

    #include<string.h>  //字符串头文件

    #include<netinet/in.h>  //地址的头文件

    #define portnum 3333

    int main()

    {

             int sockfd;

             int new_fd;

             char buffer[128];//定义存储数据的字节

             int nbyte;//接收到的字符串的长度

             int sin_size;

             struct sockaddr_in server_addr;

             struct sockaddr_in client_addr;

             int pid;

             //1.创建套接字

             if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

             {

                      printf("creat socket error! ");

                      exit(1);

             }

             //2.1 设置要绑定的地址

             bzero(&server_addr, sizeof(struct sockaddr_in));//清零

             server_addr.sin_family = AF_INET;  //网络协议

             server_addr.sin_port = htons(portnum);  //端口,超过两个字节就要转换

             server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//表示任意地址,超过两个字节就要转换

             //2.2 绑定地址

             bind(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr));//表示指针的强制转换

             //3.监听端口

             listen(sockfd, 5);

             while(1)

             {

                      //4.等待连接

                      sin_size = sizeof(struct sockaddr);

                      new_fd = accept(sockfd, (struct sockaddr *)(&client_addr), &sin_size);

                      printf("server get connection from %s ", inet_ntoa(client_addr.sin_addr));//取客户机的ip地址,并且将整型地址转换成字符串地址

                      //创建子进程,由子进程来处理数据

                      if(pid=fork() == 0) //创建子进程,如果pid等于0就是子进程,不等于0是父进程

                      {

                               //5.接收数据

                               nbyte = recv(new_fd,buffer,128,0);

                               buffer[nbyte] = '';//字符串的结束符

                               printf("server received: %s ",buffer);

                               close(new_fd);

                               close(sockfd);

                               exit(0);

                      }

                      else if(pid<0)

                               printf("fork error! ");

                      //6.结束连接

                      close(new_fd);

             }

             close(sockfd);

             return 0;

    }

    tcp_client.c还用24课的程序。

    运行结果:我们可以在三个端口中分别启用tcp_server_fork,tcp_client,tcp_client。我们会看到tcp_server_fork程序可以同时的去处理两个客户机的程序。

  • 相关阅读:
    艾伟也谈项目管理,如何让网民爱上你的网站 狼人:
    Oracle2
    万源之源之drupal7
    万源之源之drupal 之 drupal_flush_all_caches
    JavaSocket客户端,服务端通信
    windows下的bat编写经验笔记
    百度音乐搜索不公开API
    重读《Agile Retrospective敏捷回顾》一书
    Binary Search Tree 二叉搜索树 C++
    MFC控件(4):List Box
  • 原文地址:https://www.cnblogs.com/free-1122/p/11357338.html
Copyright © 2020-2023  润新知