1. 程式人生 > >78.pipe多管道雲端,客戶端通信

78.pipe多管道雲端,客戶端通信

創建 初始 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;
    
    5 HANDLE hpipe;//管道信息 6 HANDLE hevent;//事件用於初始化一個結構體用於連接管道,並存儲連接的信息 7 }PIPE_ST;

  • 創建結構體
    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(
    
    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("\n%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 printf("sever start"); 27 28 }

  • 線程函數
     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多管道雲端,客戶端通信