zoukankan      html  css  js  c++  java
  • 82.管道实现cgi内存多线程查询

    总体思路就是客户端写入要查询的数据到管道中,服务器端从管道读取,然后写入随机文件,再把文件名写入管道,然后客户端再读取文件

    服务器端


    • 设置缓冲区大写,设置管道名字,以及标识有多少个线程等
      1 //设置缓存区大小
      2 #define SIZE 4096
      3 //最多有多少线程
      4 #define MAX_CONNECT 128
      5 //一开始有10个线程存在
      6 int  startthreadnum = 10;
      7 //管道名字
      8 char  pipename[128] = "\\.\Pipe\cloudpipe";
      1 //文件路径
      2 #define  path  "C:\Program Files\Apache Software Foundation\Apache2.2\cgi-bin\kaifang.txt"
      3 //查询结果存放的路径
      4 char randpath[1000] = "";
      5 //全局的二级指针
      6 char  ** g_pp;
      7 //标示有多少行
      8 int   imax = 15151574;
    • 创建句柄结构体
       1 //结构体,hpipe存储管道信息,hevent用于给结构体初始化,存放连接管道的信息
       2 typedef struct info
       3 {
       4     HANDLE hthread;
       5     HANDLE hpipe;
       6     HANDLE hevent;
       7 
       8 }PIPE_ST;
       9 
      10 //创建128个结构体
      11 PIPE_ST  pipeinst[MAX_CONNECT];
    • 随机生成文件名存放查询的结果
      1 //随机生成文件名存放查询的结果
      2 void run()
      3 {
      4     time_t ts;
      5     srand((unsigned int)time(&ts));
      6     sprintf(randpath, "C:\Program Files\Apache Software Foundation\Apache2.2\cgi-bin\%d.txt", rand());
      7 }
    • 文件载入内存
       1 //载入内存
       2 void loadfromfile()
       3 {
       4     //分配指针数组
       5     g_pp = (char **)malloc(sizeof(char*)*imax);     
       6     //内存清零
       7     memset(g_pp, '', sizeof(char*)*imax);
       8 
       9     //以读的方式打开文件
      10     FILE *pf = fopen(path, "r");
      11     if (pf == NULL)
      12     {
      13         printf("文件打开失败");
      14         return -1;
      15     }
      16     else
      17     {
      18         for (int i = 0; i < imax; i++)
      19         {
      20             char str[1024] = { 0 };
      21             //按行读取
      22             fgets(str, 1024, pf);
      23             str[1024 - 1] = '';
      24             int  strlength = strlen(str);
      25 
      26             //分配内存
      27             g_pp[i] = malloc(sizeof(char)*(strlength + 1));
      28 
      29             //拷贝到分配的内存
      30             if (g_pp[i] != NULL)
      31             {
      32                 strcpy(g_pp[i], str);
      33             }
      34         }
      35         fclose(pf);//关闭
      36     }
      37 }
    • 查询函数
       1 //查询
       2 void search(char *str,char * randpath)
       3 {
       4     //写的模式打开
       5     FILE *pf = fopen(randpath, "w");
       6     if (g_pp != NULL)
       7     {
       8 
       9         for (int i = 0; i < imax; i++)
      10         {
      11             if (g_pp[i] != NULL)
      12             {
      13                 //查询
      14                 char *p = strstr(g_pp[i], str);
      15                 if (p != NULL)
      16                 {
      17                     fputs(g_pp[i], pf);//输出到文件
      18                 }
      19             }
      20         }
      21     }
      22     fclose(pf);
      23 }
    • 线程函数,查询结果写入随机文件,文件名再写入管道
       1 //线程函数
       2 DWORD WINAPI severThread(void *lp)
       3 {
       4     //读取到的个数
       5     DWORD nread = 0;
       6     //写入的个数
       7     DWORD nwrite = 0;
       8     //用于判断IO
       9     DWORD dwbyte = 0;
      10     //缓存区
      11     char szbuf[SIZE] = { 0 };
      12     //获取当前结构体
      13     PIPE_ST curpipe = *(PIPE_ST*)lp;
      14     //利用event初始化一个结构体
      15     OVERLAPPED overlap = { 0, 0, 0, 0, curpipe.hevent };
      16 
      17     while (1)
      18     {
      19         //数据清零
      20         memset(szbuf, 0, sizeof(szbuf));
      21         //链接管道,信息写入overlap
      22         ConnectNamedPipe(curpipe.hpipe, &overlap);
      23         //等待连接完成 
      24         WaitForSingleObject(curpipe.hevent, INFINITE);
      25         //检测IO,如果IO错误则退出
      26         if (!GetOverlappedResult(curpipe.hpipe, &overlap, &dwbyte, TRUE))
      27         {
      28             break;
      29         }
      30         //读取管道中的数据到szbuf,最多读取SIZE个
      31         if (!ReadFile(curpipe.hpipe, szbuf, SIZE, &nread, NULL))
      32         {
      33             puts("read fail");
      34             break;
      35         }
      36         
      37         char searchstr[100] = { 0 };
      38         //去读查询谁
      39         sscanf(szbuf, "%s", searchstr);
      40 
      41         //路径配置
      42         run();
      43         //查询
      44         search(searchstr, randpath);
      45 
      46         //清零
      47         memset(szbuf, 0, sizeof(szbuf));
      48         //把路径写入管道
      49         sprintf(szbuf, "%s", randpath);
      50         WriteFile(curpipe.hpipe, szbuf, strlen(szbuf), &nwrite, NULL);//写入
      51         //断开与管道的连接
      52         DisconnectNamedPipe(curpipe.hpipe);
      53     }
      54     return 0;
      55 }
    • 初始化结构体并创建线程
       1 //初始化结构体并创建线程
       2 void start()
       3 {
       4     for (int i = 0; i < startthreadnum; i++)
       5     {
       6         //创建管道,如果同名,则操作同一个管道
       7         pipeinst[i].hpipe = CreateNamedPipeA(
       8             pipename,//管道名称
       9             PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,//管道读写属性
      10             PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,//消息模式,读模式,等待模式阻塞
      11             10,//最大个数
      12             0,//输出缓冲区大小
      13             0,//输入缓冲区大小
      14             1000,//超时,无限等待
      15             NULL);
      16         if (pipeinst[i].hpipe == INVALID_HANDLE_VALUE)
      17         {
      18             printf("
      %d失败", i);
      19             return;
      20         }
      21         //创建事件
      22         pipeinst[i].hevent = CreateEventA(NULL, FALSE, FALSE, FALSE);//创建事件
      23         //创建线程
      24         pipeinst[i].hthread = CreateThread(NULL, 0, severThread, &pipeinst[i], 0, NULL);
      25 
      26     }
      27     printf("sever start");
      28 
      29 }
    • 释放内存
       1 //释放内存
       2 void end()
       3 {
       4     for (int i = 0; i < 10;i++)
       5     {
       6         CloseHandle(pipeinst[i].hthread);
       7         CloseHandle(pipeinst[i].hevent);
       8         CloseHandle(pipeinst[i].hpipe);
       9     }
      10 }
    • 主函数
       1 //主函数
       2 void main()
       3 {
       4     //载入内存
       5     loadfromfile();
       6     //创建线程                            开始查询
       7     start();
       8     system("pause");
       9 
      10 }

    客户端


    • 设置缓存区,以及管道名字和管道句柄
      1 //缓存区大小
      2 #define SIZE 4096
      3 //管道名字
      4 char  pipename[128] = "\\.\Pipe\cloudpipe";
      5 //管道句柄
      6 HANDLE m_pipe = NULL;
    • CGI编码格式转换到str中
       1 //CGI编码格式转换到str中
       2 char* change(char *str)
       3 {
       4     char *tempstr = malloc(strlen(str) + 1);
       5     int x = 0, y = 0;
       6     char assii_1, assii_2;
       7     while (tempstr[x])
       8     {
       9         if ((tempstr[x] = str[y]) == '%')
      10         {
      11             if (str[y + 1] >= 'A')
      12             {
      13                 assii_1 = str[y + 1] - 55;
      14 
      15             }
      16             else
      17             {
      18                 assii_1 = str[y + 1] - 48;
      19             }
      20             if (str[y + 2] >= 'A')
      21             {
      22                 assii_2 = str[y + 2] - 55;
      23             }
      24             else
      25             {
      26                 assii_2 = str[y + 2] - 48;
      27             }
      28             tempstr[x] = assii_1 * 16 + assii_2;
      29             y += 2;
      30         }
      31         x++;
      32         y++;
      33     }
      34     tempstr[x] = '';
      35     return tempstr;
      36 }
    • 主函数
       1 void main()
       2 {
       3     printf("Content-type:text/html
      
      ");//换行
       4 
       5     system("ipconfig");//服务器不稳定因素,适当中断
       6 
       7     //获取表单信息,并对信息进行处理
       8     char szpost[256] = { 0 };
       9     gets(szpost);
      10     printf("%s", szpost);
      11 
      12     char*p1 = strchr(szpost, '&');
      13     if (p1 != NULL)
      14     {
      15         *p1 = '';
      16     }
      17     printf("<br>%s", szpost + 5);
      18     printf("<br>%s", change(szpost + 5));
      19 
      20     char *p2 = strchr(p1 + 1, '&');
      21     if (p2 != NULL)
      22     {
      23         *p2 = '';
      24     }
      25     printf("<br>%s", p1 + 6);
      26     printf("<br>%s", change(p1 + 6));
      27     
      28     //打开管道
      29     m_pipe = CreateFileA(pipename, //名称
      30         GENERIC_WRITE | GENERIC_READ,//读写
      31         0,//共享属性,1独有
      32         NULL,//默认安全属性
      33         OPEN_EXISTING,//打开已经存在的
      34         FILE_ATTRIBUTE_NORMAL,
      35         NULL);
      36 
      37     if (m_pipe == INVALID_HANDLE_VALUE)
      38     {
      39         printf("失败");
      40         return;
      41     }
      42 
      43     int nwrite;
      44     int nread;
      45 
      46     char winfo[1024] = { 0 };
      47     //打印数据到winfo中
      48     sprintf(winfo, "%s", change(szpost + 5));
      49 
      50     //写入管道
      51     WriteFile(m_pipe, winfo, strlen(winfo), &nwrite, NULL);
      52     memset(winfo, 0, sizeof(winfo));
      53     //读取管道
      54     ReadFile(m_pipe, winfo, 1024, &nread, NULL);
      55 ;
      56     //打开文件,并读取
      57     FILE *pf = fopen(winfo, "r");
      58     while (!feof(pf))
      59     {
      60         char ch = fgetc(pf);
      61         if (ch=='
      ')
      62         {
      63             puts("<br>");
      64         } 
      65         else
      66         {
      67             putchar(ch);
      68         }
      69     }
      70     fclose(pf);
      71 
      72     system("pause");
      73 }

    完整代码:

    服务器

      1 #define  _CRT_SECURE_NO_WARNINGS
      2 #include<stdio.h>
      3 #include<time.h>
      4 #include<stdlib.h>
      5 #include<Windows.h>
      6 
      7 //设置缓存区大小
      8 #define SIZE 4096
      9 //最多有多少线程
     10 #define MAX_CONNECT 128
     11 //一开始有10个线程存在
     12 int  startthreadnum = 10;
     13 //管道名字
     14 char  pipename[128] = "\\.\Pipe\cloudpipe";
     15 
     16 //文件路径
     17 #define  path  "C:\Program Files\Apache Software Foundation\Apache2.2\cgi-bin\kaifang.txt"
     18 //查询结果存放的路径
     19 char randpath[1000] = "";
     20 //全局的二级指针
     21 char  ** g_pp;
     22 //标示有多少行
     23 int   imax = 15151574;
     24 
     25 //结构体,hpipe存储管道信息,hevent用于给结构体初始化,存放连接管道的信息
     26 typedef struct info
     27 {
     28     HANDLE hthread;
     29     HANDLE hpipe;
     30     HANDLE hevent;
     31 
     32 }PIPE_ST;
     33 
     34 //创建128个结构体
     35 PIPE_ST  pipeinst[MAX_CONNECT];
     36 
     37 //随机生成文件名存放查询的结果
     38 void run()
     39 {
     40     time_t ts;
     41     srand((unsigned int)time(&ts));
     42     sprintf(randpath, "C:\Program Files\Apache Software Foundation\Apache2.2\cgi-bin\%d.txt", rand());
     43 }
     44 
     45 //载入内存
     46 void loadfromfile()
     47 {
     48     //分配指针数组
     49     g_pp = (char **)malloc(sizeof(char*)*imax);     
     50     //内存清零
     51     memset(g_pp, '', sizeof(char*)*imax);
     52 
     53     //以读的方式打开文件
     54     FILE *pf = fopen(path, "r");
     55     if (pf == NULL)
     56     {
     57         printf("文件打开失败");
     58         return -1;
     59     }
     60     else
     61     {
     62         for (int i = 0; i < imax; i++)
     63         {
     64             char str[1024] = { 0 };
     65             //按行读取
     66             fgets(str, 1024, pf);
     67             str[1024 - 1] = '';
     68             int  strlength = strlen(str);
     69 
     70             //分配内存
     71             g_pp[i] = malloc(sizeof(char)*(strlength + 1));
     72 
     73             //拷贝到分配的内存
     74             if (g_pp[i] != NULL)
     75             {
     76                 strcpy(g_pp[i], str);
     77             }
     78         }
     79         fclose(pf);//关闭
     80     }
     81 }
     82 
     83 //查询
     84 void search(char *str,char * randpath)
     85 {
     86     //写的模式打开
     87     FILE *pf = fopen(randpath, "w");
     88     if (g_pp != NULL)
     89     {
     90 
     91         for (int i = 0; i < imax; i++)
     92         {
     93             if (g_pp[i] != NULL)
     94             {
     95                 //查询
     96                 char *p = strstr(g_pp[i], str);
     97                 if (p != NULL)
     98                 {
     99                     fputs(g_pp[i], pf);//输出到文件
    100                 }
    101             }
    102         }
    103     }
    104     fclose(pf);
    105 }
    106 
    107 //线程函数
    108 DWORD WINAPI severThread(void *lp)
    109 {
    110     //读取到的个数
    111     DWORD nread = 0;
    112     //写入的个数
    113     DWORD nwrite = 0;
    114     //用于判断IO
    115     DWORD dwbyte = 0;
    116     //缓存区
    117     char szbuf[SIZE] = { 0 };
    118     //获取当前结构体
    119     PIPE_ST curpipe = *(PIPE_ST*)lp;
    120     //利用event初始化一个结构体
    121     OVERLAPPED overlap = { 0, 0, 0, 0, curpipe.hevent };
    122 
    123     while (1)
    124     {
    125         //数据清零
    126         memset(szbuf, 0, sizeof(szbuf));
    127         //链接管道,信息写入overlap
    128         ConnectNamedPipe(curpipe.hpipe, &overlap);
    129         //等待连接完成 
    130         WaitForSingleObject(curpipe.hevent, INFINITE);
    131         //检测IO,如果IO错误则退出
    132         if (!GetOverlappedResult(curpipe.hpipe, &overlap, &dwbyte, TRUE))
    133         {
    134             break;
    135         }
    136         //读取管道中的数据到szbuf,最多读取SIZE个
    137         if (!ReadFile(curpipe.hpipe, szbuf, SIZE, &nread, NULL))
    138         {
    139             puts("read fail");
    140             break;
    141         }
    142         
    143         char searchstr[100] = { 0 };
    144         //去读查询谁
    145         sscanf(szbuf, "%s", searchstr);
    146 
    147         //路径配置
    148         run();
    149         //查询
    150         search(searchstr, randpath);
    151 
    152         //清零
    153         memset(szbuf, 0, sizeof(szbuf));
    154         //把路径写入管道
    155         sprintf(szbuf, "%s", randpath);
    156         WriteFile(curpipe.hpipe, szbuf, strlen(szbuf), &nwrite, NULL);//写入
    157         //断开与管道的连接
    158         DisconnectNamedPipe(curpipe.hpipe);
    159     }
    160     return 0;
    161 }
    162 
    163 //初始化结构体并创建线程
    164 void start()
    165 {
    166     for (int i = 0; i < startthreadnum; i++)
    167     {
    168         //创建管道,如果同名,则操作同一个管道
    169         pipeinst[i].hpipe = CreateNamedPipeA(
    170             pipename,//管道名称
    171             PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,//管道读写属性
    172             PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,//消息模式,读模式,等待模式阻塞
    173             10,//最大个数
    174             0,//输出缓冲区大小
    175             0,//输入缓冲区大小
    176             1000,//超时,无限等待
    177             NULL);
    178         if (pipeinst[i].hpipe == INVALID_HANDLE_VALUE)
    179         {
    180             printf("
    %d失败", i);
    181             return;
    182         }
    183         //创建事件
    184         pipeinst[i].hevent = CreateEventA(NULL, FALSE, FALSE, FALSE);//创建事件
    185         //创建线程
    186         pipeinst[i].hthread = CreateThread(NULL, 0, severThread, &pipeinst[i], 0, NULL);
    187 
    188     }
    189     printf("sever start");
    190 
    191 }
    192 
    193 //释放内存
    194 void end()
    195 {
    196     for (int i = 0; i < 10;i++)
    197     {
    198         CloseHandle(pipeinst[i].hthread);
    199         CloseHandle(pipeinst[i].hevent);
    200         CloseHandle(pipeinst[i].hpipe);
    201     }
    202 }
    203 
    204 //主函数
    205 void main()
    206 {
    207     //载入内存
    208     loadfromfile();
    209     //创建线程                            开始查询
    210     start();
    211     system("pause");
    212 
    213 }

    客户端

      1 #define  _CRT_SECURE_NO_WARNINGS
      2 #include<stdio.h>
      3 #include<time.h>
      4 #include<stdlib.h>
      5 #include<Windows.h>
      6 
      7 //缓存区大小
      8 #define SIZE 4096
      9 //管道名字
     10 char  pipename[128] = "\\.\Pipe\cloudpipe";
     11 //管道句柄
     12 HANDLE m_pipe = NULL;
     13 
     14 //CGI编码格式转换到str中
     15 char* change(char *str)
     16 {
     17     char *tempstr = malloc(strlen(str) + 1);
     18     int x = 0, y = 0;
     19     char assii_1, assii_2;
     20     while (tempstr[x])
     21     {
     22         if ((tempstr[x] = str[y]) == '%')
     23         {
     24             if (str[y + 1] >= 'A')
     25             {
     26                 assii_1 = str[y + 1] - 55;
     27 
     28             }
     29             else
     30             {
     31                 assii_1 = str[y + 1] - 48;
     32             }
     33             if (str[y + 2] >= 'A')
     34             {
     35                 assii_2 = str[y + 2] - 55;
     36             }
     37             else
     38             {
     39                 assii_2 = str[y + 2] - 48;
     40             }
     41             tempstr[x] = assii_1 * 16 + assii_2;
     42             y += 2;
     43         }
     44         x++;
     45         y++;
     46     }
     47     tempstr[x] = '';
     48     return tempstr;
     49 }
     50 
     51 
     52 void main()
     53 {
     54     printf("Content-type:text/html
    
    ");//换行
     55 
     56     system("ipconfig");//服务器不稳定因素,适当中断
     57 
     58     //获取表单信息,并对信息进行处理
     59     char szpost[256] = { 0 };
     60     gets(szpost);
     61     printf("%s", szpost);
     62 
     63     char*p1 = strchr(szpost, '&');
     64     if (p1 != NULL)
     65     {
     66         *p1 = '';
     67     }
     68     printf("<br>%s", szpost + 5);
     69     printf("<br>%s", change(szpost + 5));
     70 
     71     char *p2 = strchr(p1 + 1, '&');
     72     if (p2 != NULL)
     73     {
     74         *p2 = '';
     75     }
     76     printf("<br>%s", p1 + 6);
     77     printf("<br>%s", change(p1 + 6));
     78     
     79     //打开管道
     80     m_pipe = CreateFileA(pipename, //名称
     81         GENERIC_WRITE | GENERIC_READ,//读写
     82         0,//共享属性,1独有
     83         NULL,//默认安全属性
     84         OPEN_EXISTING,//打开已经存在的
     85         FILE_ATTRIBUTE_NORMAL,
     86         NULL);
     87 
     88     if (m_pipe == INVALID_HANDLE_VALUE)
     89     {
     90         printf("失败");
     91         return;
     92     }
     93 
     94     int nwrite;
     95     int nread;
     96 
     97     char winfo[1024] = { 0 };
     98     //打印数据到winfo中
     99     sprintf(winfo, "%s", change(szpost + 5));
    100 
    101     //写入管道
    102     WriteFile(m_pipe, winfo, strlen(winfo), &nwrite, NULL);
    103     memset(winfo, 0, sizeof(winfo));
    104     //读取管道
    105     ReadFile(m_pipe, winfo, 1024, &nread, NULL);
    106 ;
    107     //打开文件,并读取
    108     FILE *pf = fopen(winfo, "r");
    109     while (!feof(pf))
    110     {
    111         char ch = fgetc(pf);
    112         if (ch=='
    ')
    113         {
    114             puts("<br>");
    115         } 
    116         else
    117         {
    118             putchar(ch);
    119         }
    120     }
    121     fclose(pf);
    122 
    123     system("pause");
    124 }
  • 相关阅读:
    MYSQL优化
    linux 基础知识 之基础系统管理2
    mysql数据库读写分离+高可用
    Varnish代理缓存服务器
    tomcat
    Memcached, Redis, MongoDB区别、特点、使用场景
    session共享
    基于docker的zabbix服务搭建
    php-fpm 启动后没有监听端口9000
    学习网站
  • 原文地址:https://www.cnblogs.com/xiaochi/p/8455954.html
Copyright © 2011-2022 走看看