82.管道实现cgi内存多线程查询
2024-08-31 20:09:33
总体思路就是客户端写入要查询的数据到管道中,服务器端从管道读取,然后写入随机文件,再把文件名写入管道,然后客户端再读取文件
服务器端
- 设置缓冲区大写,设置管道名字,以及标识有多少个线程等
//设置缓存区大小
#define SIZE 4096
//最多有多少线程
#define MAX_CONNECT 128
//一开始有10个线程存在
int startthreadnum = ;
//管道名字
char pipename[] = "\\\\.\\Pipe\\cloudpipe";//文件路径
#define path "C:\\Program Files\\Apache Software Foundation\\Apache2.2\\cgi-bin\\kaifang.txt"
//查询结果存放的路径
char randpath[] = "";
//全局的二级指针
char ** g_pp;
//标示有多少行
int imax = ; - 创建句柄结构体
//结构体,hpipe存储管道信息,hevent用于给结构体初始化,存放连接管道的信息
typedef struct info
{
HANDLE hthread;
HANDLE hpipe;
HANDLE hevent; }PIPE_ST; //创建128个结构体
PIPE_ST pipeinst[MAX_CONNECT]; - 随机生成文件名存放查询的结果
//随机生成文件名存放查询的结果
void run()
{
time_t ts;
srand((unsigned int)time(&ts));
sprintf(randpath, "C:\\Program Files\\Apache Software Foundation\\Apache2.2\\cgi-bin\\%d.txt", rand());
} - 文件载入内存
//载入内存
void loadfromfile()
{
//分配指针数组
g_pp = (char **)malloc(sizeof(char*)*imax);
//内存清零
memset(g_pp, '\0', sizeof(char*)*imax); //以读的方式打开文件
FILE *pf = fopen(path, "r");
if (pf == NULL)
{
printf("文件打开失败");
return -;
}
else
{
for (int i = ; i < imax; i++)
{
char str[] = { };
//按行读取
fgets(str, , pf);
str[ - ] = '\0';
int strlength = strlen(str); //分配内存
g_pp[i] = malloc(sizeof(char)*(strlength + )); //拷贝到分配的内存
if (g_pp[i] != NULL)
{
strcpy(g_pp[i], str);
}
}
fclose(pf);//关闭
}
} - 查询函数
//查询
void search(char *str,char * randpath)
{
//写的模式打开
FILE *pf = fopen(randpath, "w");
if (g_pp != NULL)
{ for (int i = ; i < imax; i++)
{
if (g_pp[i] != NULL)
{
//查询
char *p = strstr(g_pp[i], str);
if (p != NULL)
{
fputs(g_pp[i], pf);//输出到文件
}
}
}
}
fclose(pf);
} - 线程函数,查询结果写入随机文件,文件名再写入管道
//线程函数
DWORD WINAPI severThread(void *lp)
{
//读取到的个数
DWORD nread = ;
//写入的个数
DWORD nwrite = ;
//用于判断IO
DWORD dwbyte = ;
//缓存区
char szbuf[SIZE] = { };
//获取当前结构体
PIPE_ST curpipe = *(PIPE_ST*)lp;
//利用event初始化一个结构体
OVERLAPPED overlap = { , , , , curpipe.hevent }; while ()
{
//数据清零
memset(szbuf, , sizeof(szbuf));
//链接管道,信息写入overlap
ConnectNamedPipe(curpipe.hpipe, &overlap);
//等待连接完成
WaitForSingleObject(curpipe.hevent, INFINITE);
//检测IO,如果IO错误则退出
if (!GetOverlappedResult(curpipe.hpipe, &overlap, &dwbyte, TRUE))
{
break;
}
//读取管道中的数据到szbuf,最多读取SIZE个
if (!ReadFile(curpipe.hpipe, szbuf, SIZE, &nread, NULL))
{
puts("read fail");
break;
} char searchstr[] = { };
//去读查询谁
sscanf(szbuf, "%s", searchstr); //路径配置
run();
//查询
search(searchstr, randpath); //清零
memset(szbuf, , sizeof(szbuf));
//把路径写入管道
sprintf(szbuf, "%s", randpath);
WriteFile(curpipe.hpipe, szbuf, strlen(szbuf), &nwrite, NULL);//写入
//断开与管道的连接
DisconnectNamedPipe(curpipe.hpipe);
}
return ;
} - 初始化结构体并创建线程
//初始化结构体并创建线程
void start()
{
for (int i = ; i < startthreadnum; i++)
{
//创建管道,如果同名,则操作同一个管道
pipeinst[i].hpipe = CreateNamedPipeA(
pipename,//管道名称
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,//管道读写属性
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,//消息模式,读模式,等待模式阻塞
,//最大个数
,//输出缓冲区大小
,//输入缓冲区大小
,//超时,无限等待
NULL);
if (pipeinst[i].hpipe == INVALID_HANDLE_VALUE)
{
printf("\n%d失败", i);
return;
}
//创建事件
pipeinst[i].hevent = CreateEventA(NULL, FALSE, FALSE, FALSE);//创建事件
//创建线程
pipeinst[i].hthread = CreateThread(NULL, , severThread, &pipeinst[i], , NULL); }
printf("sever start"); } - 释放内存
//释放内存
void end()
{
for (int i = ; i < ;i++)
{
CloseHandle(pipeinst[i].hthread);
CloseHandle(pipeinst[i].hevent);
CloseHandle(pipeinst[i].hpipe);
}
} - 主函数
//主函数
void main()
{
//载入内存
loadfromfile();
//创建线程 开始查询
start();
system("pause"); }
客户端
- 设置缓存区,以及管道名字和管道句柄
//缓存区大小
#define SIZE 4096
//管道名字
char pipename[] = "\\\\.\\Pipe\\cloudpipe";
//管道句柄
HANDLE m_pipe = NULL; - CGI编码格式转换到str中
//CGI编码格式转换到str中
char* change(char *str)
{
char *tempstr = malloc(strlen(str) + );
int x = , y = ;
char assii_1, assii_2;
while (tempstr[x])
{
if ((tempstr[x] = str[y]) == '%')
{
if (str[y + ] >= 'A')
{
assii_1 = str[y + ] - ; }
else
{
assii_1 = str[y + ] - ;
}
if (str[y + ] >= 'A')
{
assii_2 = str[y + ] - ;
}
else
{
assii_2 = str[y + ] - ;
}
tempstr[x] = assii_1 * + assii_2;
y += ;
}
x++;
y++;
}
tempstr[x] = '\0';
return tempstr;
} - 主函数
void main()
{
printf("Content-type:text/html\n\n");//换行 system("ipconfig");//服务器不稳定因素,适当中断 //获取表单信息,并对信息进行处理
char szpost[] = { };
gets(szpost);
printf("%s", szpost); char*p1 = strchr(szpost, '&');
if (p1 != NULL)
{
*p1 = '\0';
}
printf("<br>%s", szpost + );
printf("<br>%s", change(szpost + )); char *p2 = strchr(p1 + , '&');
if (p2 != NULL)
{
*p2 = '\0';
}
printf("<br>%s", p1 + );
printf("<br>%s", change(p1 + )); //打开管道
m_pipe = CreateFileA(pipename, //名称
GENERIC_WRITE | GENERIC_READ,//读写
,//共享属性,1独有
NULL,//默认安全属性
OPEN_EXISTING,//打开已经存在的
FILE_ATTRIBUTE_NORMAL,
NULL); if (m_pipe == INVALID_HANDLE_VALUE)
{
printf("失败");
return;
} int nwrite;
int nread; char winfo[] = { };
//打印数据到winfo中
sprintf(winfo, "%s", change(szpost + )); //写入管道
WriteFile(m_pipe, winfo, strlen(winfo), &nwrite, NULL);
memset(winfo, , sizeof(winfo));
//读取管道
ReadFile(m_pipe, winfo, , &nread, NULL);
;
//打开文件,并读取
FILE *pf = fopen(winfo, "r");
while (!feof(pf))
{
char ch = fgetc(pf);
if (ch=='\n')
{
puts("<br>");
}
else
{
putchar(ch);
}
}
fclose(pf); system("pause");
}
完整代码:
服务器
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<Windows.h> //设置缓存区大小
#define SIZE 4096
//最多有多少线程
#define MAX_CONNECT 128
//一开始有10个线程存在
int startthreadnum = ;
//管道名字
char pipename[] = "\\\\.\\Pipe\\cloudpipe"; //文件路径
#define path "C:\\Program Files\\Apache Software Foundation\\Apache2.2\\cgi-bin\\kaifang.txt"
//查询结果存放的路径
char randpath[] = "";
//全局的二级指针
char ** g_pp;
//标示有多少行
int imax = ; //结构体,hpipe存储管道信息,hevent用于给结构体初始化,存放连接管道的信息
typedef struct info
{
HANDLE hthread;
HANDLE hpipe;
HANDLE hevent; }PIPE_ST; //创建128个结构体
PIPE_ST pipeinst[MAX_CONNECT]; //随机生成文件名存放查询的结果
void run()
{
time_t ts;
srand((unsigned int)time(&ts));
sprintf(randpath, "C:\\Program Files\\Apache Software Foundation\\Apache2.2\\cgi-bin\\%d.txt", rand());
} //载入内存
void loadfromfile()
{
//分配指针数组
g_pp = (char **)malloc(sizeof(char*)*imax);
//内存清零
memset(g_pp, '\0', sizeof(char*)*imax); //以读的方式打开文件
FILE *pf = fopen(path, "r");
if (pf == NULL)
{
printf("文件打开失败");
return -;
}
else
{
for (int i = ; i < imax; i++)
{
char str[] = { };
//按行读取
fgets(str, , pf);
str[ - ] = '\0';
int strlength = strlen(str); //分配内存
g_pp[i] = malloc(sizeof(char)*(strlength + )); //拷贝到分配的内存
if (g_pp[i] != NULL)
{
strcpy(g_pp[i], str);
}
}
fclose(pf);//关闭
}
} //查询
void search(char *str,char * randpath)
{
//写的模式打开
FILE *pf = fopen(randpath, "w");
if (g_pp != NULL)
{ for (int i = ; i < imax; i++)
{
if (g_pp[i] != NULL)
{
//查询
char *p = strstr(g_pp[i], str);
if (p != NULL)
{
fputs(g_pp[i], pf);//输出到文件
}
}
}
}
fclose(pf);
} //线程函数
DWORD WINAPI severThread(void *lp)
{
//读取到的个数
DWORD nread = ;
//写入的个数
DWORD nwrite = ;
//用于判断IO
DWORD dwbyte = ;
//缓存区
char szbuf[SIZE] = { };
//获取当前结构体
PIPE_ST curpipe = *(PIPE_ST*)lp;
//利用event初始化一个结构体
OVERLAPPED overlap = { , , , , curpipe.hevent }; while ()
{
//数据清零
memset(szbuf, , sizeof(szbuf));
//链接管道,信息写入overlap
ConnectNamedPipe(curpipe.hpipe, &overlap);
//等待连接完成
WaitForSingleObject(curpipe.hevent, INFINITE);
//检测IO,如果IO错误则退出
if (!GetOverlappedResult(curpipe.hpipe, &overlap, &dwbyte, TRUE))
{
break;
}
//读取管道中的数据到szbuf,最多读取SIZE个
if (!ReadFile(curpipe.hpipe, szbuf, SIZE, &nread, NULL))
{
puts("read fail");
break;
} char searchstr[] = { };
//去读查询谁
sscanf(szbuf, "%s", searchstr); //路径配置
run();
//查询
search(searchstr, randpath); //清零
memset(szbuf, , sizeof(szbuf));
//把路径写入管道
sprintf(szbuf, "%s", randpath);
WriteFile(curpipe.hpipe, szbuf, strlen(szbuf), &nwrite, NULL);//写入
//断开与管道的连接
DisconnectNamedPipe(curpipe.hpipe);
}
return ;
} //初始化结构体并创建线程
void start()
{
for (int i = ; i < startthreadnum; i++)
{
//创建管道,如果同名,则操作同一个管道
pipeinst[i].hpipe = CreateNamedPipeA(
pipename,//管道名称
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,//管道读写属性
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,//消息模式,读模式,等待模式阻塞
,//最大个数
,//输出缓冲区大小
,//输入缓冲区大小
,//超时,无限等待
NULL);
if (pipeinst[i].hpipe == INVALID_HANDLE_VALUE)
{
printf("\n%d失败", i);
return;
}
//创建事件
pipeinst[i].hevent = CreateEventA(NULL, FALSE, FALSE, FALSE);//创建事件
//创建线程
pipeinst[i].hthread = CreateThread(NULL, , severThread, &pipeinst[i], , NULL); }
printf("sever start"); } //释放内存
void end()
{
for (int i = ; i < ;i++)
{
CloseHandle(pipeinst[i].hthread);
CloseHandle(pipeinst[i].hevent);
CloseHandle(pipeinst[i].hpipe);
}
} //主函数
void main()
{
//载入内存
loadfromfile();
//创建线程 开始查询
start();
system("pause"); }
客户端
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<Windows.h> //缓存区大小
#define SIZE 4096
//管道名字
char pipename[] = "\\\\.\\Pipe\\cloudpipe";
//管道句柄
HANDLE m_pipe = NULL; //CGI编码格式转换到str中
char* change(char *str)
{
char *tempstr = malloc(strlen(str) + );
int x = , y = ;
char assii_1, assii_2;
while (tempstr[x])
{
if ((tempstr[x] = str[y]) == '%')
{
if (str[y + ] >= 'A')
{
assii_1 = str[y + ] - ; }
else
{
assii_1 = str[y + ] - ;
}
if (str[y + ] >= 'A')
{
assii_2 = str[y + ] - ;
}
else
{
assii_2 = str[y + ] - ;
}
tempstr[x] = assii_1 * + assii_2;
y += ;
}
x++;
y++;
}
tempstr[x] = '\0';
return tempstr;
} void main()
{
printf("Content-type:text/html\n\n");//换行 system("ipconfig");//服务器不稳定因素,适当中断 //获取表单信息,并对信息进行处理
char szpost[] = { };
gets(szpost);
printf("%s", szpost); char*p1 = strchr(szpost, '&');
if (p1 != NULL)
{
*p1 = '\0';
}
printf("<br>%s", szpost + );
printf("<br>%s", change(szpost + )); char *p2 = strchr(p1 + , '&');
if (p2 != NULL)
{
*p2 = '\0';
}
printf("<br>%s", p1 + );
printf("<br>%s", change(p1 + )); //打开管道
m_pipe = CreateFileA(pipename, //名称
GENERIC_WRITE | GENERIC_READ,//读写
,//共享属性,1独有
NULL,//默认安全属性
OPEN_EXISTING,//打开已经存在的
FILE_ATTRIBUTE_NORMAL,
NULL); if (m_pipe == INVALID_HANDLE_VALUE)
{
printf("失败");
return;
} int nwrite;
int nread; char winfo[] = { };
//打印数据到winfo中
sprintf(winfo, "%s", change(szpost + )); //写入管道
WriteFile(m_pipe, winfo, strlen(winfo), &nwrite, NULL);
memset(winfo, , sizeof(winfo));
//读取管道
ReadFile(m_pipe, winfo, , &nread, NULL);
;
//打开文件,并读取
FILE *pf = fopen(winfo, "r");
while (!feof(pf))
{
char ch = fgetc(pf);
if (ch=='\n')
{
puts("<br>");
}
else
{
putchar(ch);
}
}
fclose(pf); system("pause");
}
最新文章
- CentOS随笔 不断添加
- AngularJS 初用总结
- Oracle 多表查询优化
- jquery datatables双击,获取行号。
- Nginx 1.4.7图片缓存服务器
- cocos2dx 3.2 定义自己使用rapidjson阅读json数据
- Unity 3D Framework Designing(1)—— MVVM 模式的设计和实施(Part 2)
- bigdecimal更精确的浮点处理方式
- 01. SELECT显示和PRINT打印超长的字符
- 【SSH系列】Hibernate映射 -- 继承映射
- PHP常用函数总结(180多个)[持续更新中...]
- pycharm 中自动补全代码提示前符号 p,m ,c,v, f 是什么意思
- 【java编程】java中的移位运算符
- ELK-elasticsearch-6.3.2部署
- u3d 元件的克隆 Cloning of u3d components
- 防止UI界面被输入法遮挡(画面随输入法自适应)
- Struct2中自定义的Filter无效
- PHP之mb_strstr使用
- HDU 2689.Sort it-冒泡排序
- sessionstorage:本地临时存储