78.pipe多管道雲端,客戶端通信
阿新 • • 發佈:2018-02-20
創建 初始 sys 事件 消息 rand() word shell overlap
壓力測試截圖:
雲端
- 定義管道緩存區大小,最多連接數量(線程個數),當前線程個數,管道名字
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 typedef struct info 3 { 4 HANDLE hthread;
- 創建結構體
1 //128個結構體 2 PIPE_ST pipeinst[MAX_CONNECT];
- 初始化結構體,並開啟線程
1 //創建管道,事件,並啟動線程 2 void start() 3 { 4 for (int i = 0; i <startthreadnum; i++) 5 { 6 //創建管道 7 pipeinst[i].hpipe = CreateNamedPipeA(
- 線程函數
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 char szbuf[SIZE] = { 0 }; 11 12 //獲取當前結構體 13 PIPE_ST curpipe = *(PIPE_ST*)lp; 14 //用事件初始化一個結構體用於連接管道,存儲連接的信息 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,如果完成就跳出 26 if (!GetOverlappedResult(curpipe.hpipe,&overlap,&dwbyte,TRUE)) 27 { 28 break; 29 } 30 //讀取管道中的數據到szbuf中 31 if (!ReadFile(curpipe.hpipe,szbuf,SIZE,&nread,NULL)) 32 { 33 puts("read fail"); 34 break; 35 } 36 //從讀取的數據中獲取數據 37 int a, b; 38 sscanf(szbuf, "%d %d", &a, &b); 39 //緩存區清零 40 memset(szbuf, 0, sizeof(szbuf)); 41 //計算結果 42 sprintf(szbuf, "%d", a + b); 43 //把結果寫入管道 44 WriteFile(curpipe.hpipe, szbuf, strlen(szbuf), &nwrite, NULL); 45 //斷開連接 46 DisconnectNamedPipe(curpipe.hpipe); 47 } 48 return 0; 49 }
客戶端
- 定義管道緩存區大小,管道名字,以及管道連接的句柄
1 #define SIZE 4096 2 char pipename[128] = "\\\\.\\Pipe\\cloudpipe"; 3 HANDLE m_pipe = NULL;
- 生成隨機數用於給服務器進行計算
1 int a; 2 int b; 3 void run() 4 { 5 time_t ts; 6 unsigned int num = time(&ts); 7 srand(num); 8 a = rand() % 1000; 9 b= rand() % 1000; 10 }
- 打開管道,並向管道中寫入數據,再讀取計算後的結果
1 m_pipe = CreateFileA(pipename, //名稱 2 GENERIC_WRITE | GENERIC_READ,//讀寫 3 0,//共享屬性,1獨有 4 NULL,//默認安全屬性 5 OPEN_EXISTING,//打開已經存在的 6 FILE_ATTRIBUTE_NORMAL, 7 NULL); 8 9 if (m_pipe==INVALID_HANDLE_VALUE) 10 { 11 printf("失敗"); 12 return; 13 } 14 //存儲讀取寫入了多少個 15 int nwrite; 16 int nread; 17 //生成隨機數 18 run(); 19 //存儲寫入的數據 20 char winfo[1024] = { 0 }; 21 //格式到winfo中 22 sprintf(winfo, "%d %d", a, b); 23 //寫入管道 24 WriteFile(m_pipe, winfo, strlen(winfo), &nwrite, NULL); 25 //清零 26 memset(winfo, 0, sizeof(winfo)); 27 //讀取管道計算後的數據到winfo中 28 ReadFile(m_pipe, winfo, 1024, &nread, NULL); 29 //獲取服務器計算的結果 30 int res; 31 sscanf(winfo, "%d", &res); 32 printf("\n%d+%d=%d", a, b, res);
服務器端完整代碼:
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 typedef struct info 18 { 19 HANDLE hthread; 20 HANDLE hpipe;//管道信息 21 HANDLE hevent;//事件用於初始化一個結構體用於連接管道,並存儲連接的信息 22 }PIPE_ST; 23 24 //128個結構體 25 PIPE_ST pipeinst[MAX_CONNECT]; 26 27 //服務器線程 28 DWORD WINAPI severThread(void *lp) 29 { 30 //存儲讀取的數量 31 DWORD nread = 0; 32 //存儲寫入的數 33 DWORD nwrite = 0; 34 //檢測IO是否完成 35 DWORD dwbyte = 0; 36 char szbuf[SIZE] = { 0 }; 37 38 //獲取當前結構體 39 PIPE_ST curpipe = *(PIPE_ST*)lp; 40 //用事件初始化一個結構體用於連接管道,存儲連接的信息 41 OVERLAPPED overlap = { 0, 0, 0, 0, curpipe.hevent }; 42 43 while (1) 44 { 45 //數據清零 46 memset(szbuf, 0, sizeof(szbuf)); 47 //鏈接上管道,並把信息寫入overlap 48 ConnectNamedPipe(curpipe.hpipe, &overlap); 49 //等待 50 WaitForSingleObject(curpipe.hevent, INFINITE); 51 //檢測IO,如果完成就跳出 52 if (!GetOverlappedResult(curpipe.hpipe,&overlap,&dwbyte,TRUE)) 53 { 54 break; 55 } 56 //讀取管道中的數據到szbuf中 57 if (!ReadFile(curpipe.hpipe,szbuf,SIZE,&nread,NULL)) 58 { 59 puts("read fail"); 60 break; 61 } 62 //從讀取的數據中獲取數據 63 int a, b; 64 sscanf(szbuf, "%d %d", &a, &b); 65 //緩存區清零 66 memset(szbuf, 0, sizeof(szbuf)); 67 //計算結果 68 sprintf(szbuf, "%d", a + b); 69 //把結果寫入管道 70 WriteFile(curpipe.hpipe, szbuf, strlen(szbuf), &nwrite, NULL); 71 //斷開連接 72 DisconnectNamedPipe(curpipe.hpipe); 73 } 74 return 0; 75 } 76 77 //創建管道,事件,並啟動線程 78 void start() 79 { 80 for (int i = 0; i <startthreadnum; i++) 81 { 82 //創建管道 83 pipeinst[i].hpipe = CreateNamedPipeA( 84 pipename,//管道名稱 85 PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,//管道讀寫屬性 86 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,//消息模式,讀模式,等待模式阻塞 87 10,//最多使用本管道的實例個數 88 0,//輸出緩沖區大小 89 0,//輸入緩沖區大小 90 1000,//超時,無限等待 91 NULL); 92 if (pipeinst[i].hpipe == INVALID_HANDLE_VALUE) 93 { 94 printf("\n%d失敗",i); 95 return; 96 } 97 //創建事件 98 pipeinst[i].hevent = CreateEventA(NULL, FALSE, FALSE, FALSE);//創建事件 99 //創建線程 100 pipeinst[i].hthread=CreateThread(NULL,0,severThread,&pipeinst[i],0,NULL); 101 } 102 printf("sever start"); 103 104 } 105 106 void main() 107 { 108 start(); 109 system("pause"); 110 }
客戶端完整代碼:
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<time.h> 4 #include<stdlib.h> 5 #include<Windows.h> 6 7 #define SIZE 4096 8 char pipename[128] = "\\\\.\\Pipe\\cloudpipe"; 9 HANDLE m_pipe = NULL; 10 11 12 int a; 13 int b; 14 void run() 15 { 16 time_t ts; 17 unsigned int num = time(&ts); 18 srand(num); 19 a = rand() % 1000; 20 b= rand() % 1000; 21 } 22 23 24 25 void main() 26 { 27 m_pipe = CreateFileA(pipename, //名稱 28 GENERIC_WRITE | GENERIC_READ,//讀寫 29 0,//共享屬性,1獨有 30 NULL,//默認安全屬性 31 OPEN_EXISTING,//打開已經存在的 32 FILE_ATTRIBUTE_NORMAL, 33 NULL); 34 35 if (m_pipe==INVALID_HANDLE_VALUE) 36 { 37 printf("失敗"); 38 return; 39 } 40 //存儲讀取寫入了多少個 41 int nwrite; 42 int nread; 43 //生成隨機數 44 run(); 45 //存儲寫入的數據 46 char winfo[1024] = { 0 }; 47 //格式到winfo中 48 sprintf(winfo, "%d %d", a, b); 49 //寫入管道 50 WriteFile(m_pipe, winfo, strlen(winfo), &nwrite, NULL); 51 //清零 52 memset(winfo, 0, sizeof(winfo)); 53 //讀取管道計算後的數據到winfo中 54 ReadFile(m_pipe, winfo, 1024, &nread, NULL); 55 //獲取服務器計算的結果 56 int res; 57 sscanf(winfo, "%d", &res); 58 printf("\n%d+%d=%d", a, b, res); 59 system("pause"); 60 }
壓力測試代碼
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <Windows.h> 4 5 void main() 6 { 7 8 9 while (1) 10 { 11 for (int i = 0; i < 10;i++) 12 { 13 ShellExecuteA(NULL, "open", "E:\\工具\\20150523\\pipe\\Debug\\客戶端.exe", NULL, NULL, 1); 14 Sleep(100); 15 } 16 17 18 19 } 20 21 22 23 }
78.pipe多管道雲端,客戶端通信