当前位置:首页 > 操作系统 > Windows

windows命名管道

  命名管道是通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节。

  将命名管道作为一种网络编程方案时,它实际上建立了一个C/S通信体系,并在其中可靠的传输数据。命名管道服务器和客户机的区别在于:服务器是唯一一个有权创建命名管道的进程,也只有它能接受管道客户机的连接请求。而客户机只能同一个现成的命名管道服务器建立连接。命名管道提供了两种基本通信模式,字节模式和消息模式。在字节模式中,数据以一个连续的字节流的形式在客户机和服务器之间流动。而在消息模式中,客户机和服务器则通过一系列不连续的数据单位进行数据的收发,每次在管道上发出一条消息后,它必须作为一条完整的消息读入。

 

0x01 Server端

 

  代码流程:

  1、创建命名管道:CreateNamedPipe

  2、等待客户端连接:ConnectNamedPipe

  3、读取客户端请求数据:ReadFile

  4、向客户端回复数据:WriteFile

  5、关闭连接:DisconnectNamedPipe

  6、关闭管道:CloseHandle

 

       使用函数:

  CreateNamedPipe创建一个命名的管道

HANDLE CreateNamedPipe(  
  LPCTSTR lpName,                             // 管道名称,形式必须为.pipepipeName  
  DWORD dwOpenMode,                           // 打开管道的模式  
  DWORD dwPipeMode,                           // 管道的模式,传输数据的形式  
  DWORD nMaxInstances,                        // 最大连接客户端的个数  
  DWORD nOutBufferSize,                       // 输出缓冲区的大小  
  DWORD nInBufferSize,                        // 输入缓冲区的大小  
  DWORD nDefaultTimeOut,                      // 默认的超时时间  
  LPSECURITY_ATTRIBUTES lpSecurityAttributes  // 安全属性,一般为NULL  
);  

  ConnectNamedPipe等待一个客户端的连接

BOOL ConnectNamedPipe(    
  HANDLE hNamedPipe,          // 命名管道对象  
  LPOVERLAPPED lpOverlapped   // OVERLAPPED结构  
);  

  通信的操作跟我们的文件操作是一样的,通过ReadFile和WriteFile来进行读和写。

 

  通信完之后,调用DisconnectNamedPipe来进行断开连接

BOOL DisconnectNamedPipe(    
  HANDLE hNamedPipe   // 命名管道对象  
);  

  Server端源码:

技术分享 技术分享
                <span>  1</span>
                <span>//</span>
                <span> NamedPipeServer.cpp : 定义控制台应用程序的入口点。
</span>
                <span>  2</span>
                <span>//
</span>
                <span>  3</span> #include <span>"</span><span>stdafx.h</span><span>"</span><span>  4</span> #include <windows.h>  
<span>  5</span> #include <strsafe.h>  
<span>  6</span><span>  7</span><span>#define</span> BUFSIZE 4096  
<span>  8</span><span>  9</span><span>DWORD WINAPI InstanceThread(LPVOID);
</span><span> 10</span><span>VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD);
</span><span> 11</span><span> 12</span><span>int</span><span> _tmain(VOID)
</span><span> 13</span><span>{
</span><span> 14</span><span>    BOOL fConnected;
</span><span> 15</span><span>    DWORD dwThreadId;
</span><span> 16</span><span>    HANDLE hPipe, hThread;
</span><span> 17</span>     LPTSTR lpszPipename = TEXT(<span>"</span><span>\.pipeLiudadaNemaedPipe</span><span>"</span><span>);
</span><span> 18</span><span> 19</span><span>//</span><span> The main loop creates an instance of the named pipe and   
</span><span> 20</span><span>//</span><span> then waits for a client to connect to it. When the client   
</span><span> 21</span><span>//</span><span> connects, a thread is created to handle communications   
</span><span> 22</span><span>//</span><span> with that client, and the loop is repeated.   </span><span> 23</span><span> 24</span><span>for</span><span> (;;)
</span><span> 25</span><span>    {
</span><span> 26</span>         hPipe =<span> CreateNamedPipe(
</span><span> 27</span>             lpszPipename,             <span>//</span><span> pipe name            指向管道名称的指针</span><span> 28</span>             PIPE_ACCESS_DUPLEX,       <span>//</span><span> read/write access    管道打开模式</span><span> 29</span>             PIPE_TYPE_MESSAGE |       <span>//</span><span> message type pipe    管道模式</span><span> 30</span>             PIPE_READMODE_MESSAGE |   <span>//</span><span> message-read mode   </span><span> 31</span>             PIPE_WAIT,                <span>//</span><span> blocking mode   </span><span> 32</span>             PIPE_UNLIMITED_INSTANCES, <span>//</span><span> max. instances       最大实例数 </span><span> 33</span>             BUFSIZE,                  <span>//</span><span> output buffer size   输出缓存大小</span><span> 34</span>             BUFSIZE,                  <span>//</span><span> input buffer size    输入缓存大小</span><span> 35</span><span>0</span>,                        <span>//</span><span> client time-out      超时设置</span><span> 36</span>             NULL);                    <span>//</span><span> default security attribute   </span><span> 37</span><span> 38</span><span>if</span> (hPipe ==<span> INVALID_HANDLE_VALUE)
</span><span> 39</span><span>        {
</span><span> 40</span>             printf(<span>"</span><span>CreatePipe failed</span><span>"</span><span>);
</span><span> 41</span><span>return</span><span>0</span><span>;
</span><span> 42</span><span>        }
</span><span> 43</span><span> 44</span><span>//</span><span> Wait for the client to connect; if it succeeds,   
</span><span> 45</span><span>//</span><span> the function returns a nonzero value. If the function  
</span><span> 46</span><span>//</span><span> returns zero, GetLastError returns ERROR_PIPE_CONNECTED.   </span><span> 47</span><span> 48</span>         fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() ==<span> ERROR_PIPE_CONNECTED);
</span><span> 49</span><span> 50</span><span>if</span><span> (fConnected)
</span><span> 51</span><span>        {
</span><span> 52</span><span>//</span><span> Create a thread for this client.   </span><span> 53</span>             hThread =<span> CreateThread(
</span><span> 54</span>                 NULL,              <span>//</span><span> no security attribute   </span><span> 55</span><span>0</span>,                 <span>//</span><span> default stack size   </span><span> 56</span>                 InstanceThread,    <span>//</span><span> thread proc  </span><span> 57</span>                 (LPVOID)hPipe,    <span>//</span><span> thread parameter   </span><span> 58</span><span>0</span>,                 <span>//</span><span> not suspended   </span><span> 59</span>                 &dwThreadId);      <span>//</span><span> returns thread ID   </span><span> 60</span><span> 61</span><span>if</span> (hThread ==<span> NULL)
</span><span> 62</span><span>            {
</span><span> 63</span>                 printf(<span>"</span><span>CreateThread failed</span><span>"</span><span>);
</span><span> 64</span><span>return</span><span>0</span><span>;
</span><span> 65</span><span>            }
</span><span> 66</span><span>else</span><span> CloseHandle(hThread);
</span><span> 67</span><span>        }
</span><span> 68</span><span>else</span><span> 69</span><span>        {
</span><span> 70</span><span>//</span><span> The client could not connect, so close the pipe.   </span><span> 71</span><span>            CloseHandle(hPipe);
</span><span> 72</span><span>        }
</span><span> 73</span><span>    }
</span><span> 74</span><span>return</span><span>1</span><span>;
</span><span> 75</span><span>}
</span><span> 76</span><span> 77</span><span>DWORD WINAPI InstanceThread(LPVOID lpvParam)
</span><span> 78</span><span>{
</span><span> 79</span><span>    TCHAR chRequest[BUFSIZE];
</span><span> 80</span><span>    TCHAR chReply[BUFSIZE];
</span><span> 81</span><span>    DWORD cbBytesRead, cbReplyBytes, cbWritten;
</span><span> 82</span><span>    BOOL fSuccess;
</span><span> 83</span><span>    HANDLE hPipe;
</span><span> 84</span><span> 85</span><span>//</span><span> The thread‘s parameter is a handle to a pipe instance.   </span><span> 86</span><span> 87</span>     hPipe =<span> (HANDLE)lpvParam;
</span><span> 88</span><span> 89</span><span>while</span> (<span>1</span><span>)
</span><span> 90</span><span>    {
</span><span> 91</span><span>//</span><span> Read client requests from the pipe.   </span><span> 92</span>         fSuccess =<span> ReadFile(
</span><span> 93</span>             hPipe,        <span>//</span><span> handle to pipe   </span><span> 94</span>             chRequest,    <span>//</span><span> buffer to receive data   </span><span> 95</span>             BUFSIZE * <span>sizeof</span>(TCHAR), <span>//</span><span> size of buffer   </span><span> 96</span>             &cbBytesRead, <span>//</span><span> number of bytes read   </span><span> 97</span>             NULL);        <span>//</span><span> not overlapped I/O   </span><span> 98</span><span> 99</span><span>if</span> (!fSuccess || cbBytesRead == <span>0</span><span>)
</span><span>100</span><span>break</span><span>;
</span><span>101</span>         printf((<span>const</span><span>char</span>*<span>)chRequest);
</span><span>102</span><span>103</span>         GetAnswerToRequest(chRequest, chReply, &<span>cbReplyBytes);
</span><span>104</span><span>105</span><span>//</span><span> Write the reply to the pipe.   </span><span>106</span>         fSuccess =<span> WriteFile(
</span><span>107</span>             hPipe,        <span>//</span><span> handle to pipe   </span><span>108</span>             chReply,      <span>//</span><span> buffer to write from   </span><span>109</span>             cbReplyBytes, <span>//</span><span> number of bytes to write   </span><span>110</span>             &cbWritten,   <span>//</span><span> number of bytes written   </span><span>111</span>             NULL);        <span>//</span><span> not overlapped I/O   </span><span>112</span><span>113</span><span>if</span> (!fSuccess || cbReplyBytes != cbWritten) <span>break</span><span>;
</span><span>114</span><span>    }
</span><span>115</span><span>116</span><span>//</span><span> Flush the pipe to allow the client to read the pipe‘s contents   
</span><span>117</span><span>//</span><span> before disconnecting. Then disconnect the pipe, and close the   
</span><span>118</span><span>//</span><span> handle to this pipe instance.   </span><span>119</span><span>120</span><span>    FlushFileBuffers(hPipe);
</span><span>121</span><span>    DisconnectNamedPipe(hPipe);
</span><span>122</span><span>    CloseHandle(hPipe);
</span><span>123</span><span>124</span><span>return</span><span>1</span><span>;
</span><span>125</span><span>}
</span><span>126</span><span>127</span><span>VOID GetAnswerToRequest(LPTSTR chRequest,
</span><span>128</span><span>    LPTSTR chReply, LPDWORD pchBytes)
</span><span>129</span><span>{
</span><span>130</span>     _tprintf(TEXT(<span>"</span><span>%s
</span><span>"</span><span>), chRequest);
</span><span>131</span>     StringCchCopy(chReply, BUFSIZE, TEXT(<span>"</span><span>Message from server</span><span>"</span><span>));
</span><span>132</span>     *pchBytes = (lstrlen(chReply) + <span>1</span>) * <span>sizeof</span><span>(TCHAR);
</span><span>133</span> }
NamedPipeServer

 

 

0x01 Client端

 

  代码流程:

  1、打开命名管道:CreateFile

  2、等待服务端响应:WaitNamedPipe

  3、切换管道为读模式:SetNamedPipeHandleState

  4、向服务端发数据:WriteFile

  5、读服务端返回的数据:ReadFile

  6、关闭管道:CloseHandle

 

  WaitNamedPipe来检查一下,命名管道是否存在:

BOOL WaitNamedPipe(    
  LPCTSTR lpNamedPipeName,  // 管道名称,形式必须为<span style="font-family: Arial, Helvetica, sans-serif;">.pipepipeName</span>  
  DWORD nTimeOut            // 超时时间,给NULL为默认的超时时间  
);  

  SetNamedPipeHandleState 设置管道的一些参数,传输模式

BOOL WINAPI SetNamedPipeHandleState(
  _In_      HANDLE hNamedPipe,//命名管道句柄
  _In_opt_  LPDWORD lpMode,//传输模式,字节流或者信息流
  _In_opt_  LPDWORD lpMaxCollectionCount,//最大字节数
  _In_opt_  LPDWORD lpCollectDataTimeout//超时
);

Client端源码:

技术分享 技术分享
                <span>  1</span>
                <span>//</span>
                <span> NamedPipeClient.cpp : 定义控制台应用程序的入口点。
</span>
                <span>  2</span>
                <span>//
</span>
                <span>  3</span>
                <span>  4</span> #include <span>"</span><span>stdafx.h</span><span>"</span><span>  5</span> #include <windows.h>  
<span>  6</span> #include <conio.h>  
<span>  7</span><span>#define</span> BUFSIZE 512  
<span>  8</span><span>  9</span><span>int</span> main(<span>int</span> argc, TCHAR *<span>argv[])
</span><span> 10</span><span>{
</span><span> 11</span><span>    HANDLE hPipe;
</span><span> 12</span>     LPTSTR lpvMessage = TEXT(<span>"</span><span>Message from client</span><span>"</span><span>);
</span><span> 13</span><span>    TCHAR chBuf[BUFSIZE];
</span><span> 14</span><span>    BOOL fSuccess;
</span><span> 15</span><span>    DWORD cbRead, cbWritten, dwMode;
</span><span> 16</span>     LPTSTR lpszPipename = TEXT(<span>"</span><span>\.pipeLiudadaNemaedPipe</span><span>"</span><span>);
</span><span> 17</span><span> 18</span><span>if</span> (argc > <span>1</span><span>)
</span><span> 19</span>         lpvMessage = argv[<span>1</span><span>];
</span><span> 20</span><span> 21</span><span>//</span><span> Try to open a named pipe; wait for it, if necessary.   </span><span> 22</span><span> 23</span><span>while</span> (<span>1</span><span>)
</span><span> 24</span><span>    {
</span><span> 25</span>         hPipe =<span> CreateFile(
</span><span> 26</span>             lpszPipename,   <span>//</span><span> pipe name   </span><span> 27</span>             GENERIC_READ |  <span>//</span><span> read and write access   </span><span> 28</span><span>            GENERIC_WRITE,
</span><span> 29</span><span>0</span>,              <span>//</span><span> no sharing   </span><span> 30</span>             NULL,           <span>//</span><span> default security attributes  </span><span> 31</span>             OPEN_EXISTING,  <span>//</span><span> opens existing pipe   </span><span> 32</span><span>0</span>,              <span>//</span><span> default attributes   </span><span> 33</span>             NULL);          <span>//</span><span> no template file   
</span><span> 34</span><span> 35</span><span>//</span><span> Break if the pipe handle is valid.   </span><span> 36</span><span> 37</span><span>if</span> (hPipe !=<span> INVALID_HANDLE_VALUE)
</span><span> 38</span><span>break</span><span>;
</span><span> 39</span><span> 40</span><span>//</span><span> Exit if an error other than ERROR_PIPE_BUSY occurs.   </span><span> 41</span><span> 42</span><span>if</span> (GetLastError() !=<span> ERROR_PIPE_BUSY)
</span><span> 43</span><span>        {
</span><span> 44</span>             printf(<span>"</span><span>Could not open pipe</span><span>"</span><span>);
</span><span> 45</span><span>return</span><span>0</span><span>;
</span><span> 46</span><span>        }
</span><span> 47</span><span> 48</span><span>//</span><span> All pipe instances are busy, so wait for 20 seconds.   </span><span> 49</span><span> 50</span><span>if</span> (!WaitNamedPipe(lpszPipename, <span>20000</span><span>))
</span><span> 51</span><span>        {
</span><span> 52</span>             printf(<span>"</span><span>Could not open pipe</span><span>"</span><span>);
</span><span> 53</span><span>return</span><span>0</span><span>;
</span><span> 54</span><span>        }
</span><span> 55</span><span>    }
</span><span> 56</span><span> 57</span><span>//</span><span> The pipe connected; change to message-read mode.   </span><span> 58</span><span> 59</span>     dwMode =<span> PIPE_READMODE_MESSAGE;
</span><span> 60</span>     fSuccess =<span> SetNamedPipeHandleState(
</span><span> 61</span>         hPipe,    <span>//</span><span> pipe handle   </span><span> 62</span>         &dwMode,  <span>//</span><span> new pipe mode   </span><span> 63</span>         NULL,     <span>//</span><span> don‘t set maximum bytes   </span><span> 64</span>         NULL);    <span>//</span><span> don‘t set maximum time   </span><span> 65</span><span>if</span> (!<span>fSuccess)
</span><span> 66</span><span>    {
</span><span> 67</span>         printf(<span>"</span><span>SetNamedPipeHandleState failed</span><span>"</span><span>);
</span><span> 68</span><span>return</span><span>0</span><span>;
</span><span> 69</span><span>    }  
</span><span> 70</span><span> 71</span><span>//</span><span> Send a message to the pipe server.   </span><span> 72</span><span> 73</span>     fSuccess =<span> WriteFile(
</span><span> 74</span>         hPipe,                  <span>//</span><span> pipe handle   </span><span> 75</span>         lpvMessage,             <span>//</span><span> message   </span><span> 76</span>         (lstrlen(lpvMessage) + <span>1</span>) * <span>sizeof</span>(TCHAR), <span>//</span><span> message length   </span><span> 77</span>         &cbWritten,             <span>//</span><span> bytes written   </span><span> 78</span>         NULL);                  <span>//</span><span> not overlapped   </span><span> 79</span><span>if</span> (!<span>fSuccess)
</span><span> 80</span><span>    {
</span><span> 81</span>         printf(<span>"</span><span>WriteFile failed</span><span>"</span><span>);
</span><span> 82</span><span>return</span><span>0</span><span>;
</span><span> 83</span><span>    }
</span><span> 84</span><span> 85</span><span>do</span><span> 86</span><span>    {
</span><span> 87</span><span>//</span><span> Read from the pipe.   </span><span> 88</span><span> 89</span>         fSuccess =<span> ReadFile(
</span><span> 90</span>             hPipe,    <span>//</span><span> pipe handle   </span><span> 91</span>             chBuf,    <span>//</span><span> buffer to receive reply   </span><span> 92</span>             BUFSIZE * <span>sizeof</span>(TCHAR),  <span>//</span><span> size of buffer   </span><span> 93</span>             &cbRead,  <span>//</span><span> number of bytes read   </span><span> 94</span>             NULL);    <span>//</span><span> not overlapped   </span><span> 95</span><span> 96</span><span>if</span> (!fSuccess && GetLastError() !=<span> ERROR_MORE_DATA)
</span><span> 97</span><span>break</span><span>;
</span><span> 98</span><span> 99</span>         _tprintf(TEXT(<span>"</span><span>%s
</span><span>"</span><span>), chBuf);
</span><span>100</span><span>//</span><span>printf("%S
", chBuf);</span><span>101</span>     } <span>while</span> (!fSuccess);  <span>//</span><span> repeat loop if ERROR_MORE_DATA   </span><span>102</span><span>103</span><span>    getch();
</span><span>104</span><span>105</span><span>    CloseHandle(hPipe);
</span><span>106</span><span>107</span><span>return</span><span>0</span><span>;
</span><span>108</span> }
NamedPipeClient

 

原文:http://www.cnblogs.com/lsh123/p/7435401.html


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!

相关教程推荐

其他课程推荐