第三季-第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程序可以同时的去处理两个客户机的程序。

原文地址:https://www.cnblogs.com/free-1122/p/11357338.html