命名管道-MSDN例子

服务器:


  1 #include "stdafx.h"
2 #include <windows.h>
3 #include <stdio.h>
4 #include <tchar.h>
5 #include <strsafe.h>
6
7 #define BUFSIZE 512
8
9 DWORD WINAPI InstanceThread(LPVOID);
10 VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD);
11
12 int _tmain(VOID)
13 {
14 BOOL fConnected = FALSE;
15 DWORD dwThreadId = 0;
16 HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL;
17 LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");
18
19 // The main loop creates an instance of the named pipe and
20 // then waits for a client to connect to it. When the client
21 // connects, a thread is created to handle communications
22 // with that client, and this loop is free to wait for the
23 // next client connect request. It is an infinite loop.
24
25 for (;;)
26 {
27 _tprintf( TEXT("\nPipe Server: Main thread awaiting client connection on %s\n"), lpszPipename);
28 hPipe = CreateNamedPipe(
29 lpszPipename, // pipe name
30 PIPE_ACCESS_DUPLEX, // read/write access
31 PIPE_TYPE_MESSAGE | // message type pipe
32 PIPE_READMODE_MESSAGE | // message-read mode
33 PIPE_WAIT, // blocking mode
34 PIPE_UNLIMITED_INSTANCES, // max. instances
35 BUFSIZE, // output buffer size
36 BUFSIZE, // input buffer size
37 0, // client time-out
38 NULL); // default security attribute
39
40 if (hPipe == INVALID_HANDLE_VALUE)
41 {
42 _tprintf(TEXT("CreateNamedPipe failed, GLE=%d.\n"), GetLastError());
43 return -1;
44 }
45
46 // Wait for the client to connect; if it succeeds,
47 // the function returns a nonzero value. If the function
48 // returns zero, GetLastError returns ERROR_PIPE_CONNECTED.
49
50 //等待客户端接入(目前为阻塞模式)
51 fConnected = ConnectNamedPipe(hPipe, NULL) ?
52 TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
53
54 if (fConnected)
55 {
56 printf("Client connected, creating a processing thread.\n");
57
58 // Create a thread for this client.
59 hThread = CreateThread(
60 NULL, // no security attribute
61 0, // default stack size
62 InstanceThread, // thread proc
63 (LPVOID) hPipe, // thread parameter
64 0, // not suspended
65 &dwThreadId); // returns thread ID
66
67 if (hThread == NULL)
68 {
69 _tprintf(TEXT("CreateThread failed, GLE=%d.\n"), GetLastError());
70 return -1;
71 }
72 else CloseHandle(hThread);
73 }
74 else
75 // The client could not connect, so close the pipe.
76 CloseHandle(hPipe);
77
78 }
79
80 return 0;
81 }
82
83 DWORD WINAPI InstanceThread(LPVOID lpvParam)
84 // This routine is a thread processing function to read from and reply to a client
85 // via the open pipe connection passed from the main loop. Note this allows
86 // the main loop to continue executing, potentially creating more threads of
87 // of this procedure to run concurrently, depending on the number of incoming
88 // client connections.
89 {
90 HANDLE hHeap = GetProcessHeap();
91 TCHAR* pchRequest = (TCHAR*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(TCHAR));
92 TCHAR* pchReply = (TCHAR*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(TCHAR));
93
94 DWORD cbBytesRead = 0, cbReplyBytes = 0, cbWritten = 0;
95 BOOL fSuccess = FALSE;
96 HANDLE hPipe = NULL;
97
98 // Do some extra error checking since the app will keep running even if this
99 // thread fails.
100
101 if (lpvParam == NULL)
102 {
103 printf( "\nERROR - Pipe Server Failure:\n");
104 printf( " InstanceThread got an unexpected NULL value in lpvParam.\n");
105 printf( " InstanceThread exitting.\n");
106 if (pchReply != NULL) HeapFree(hHeap, 0, pchReply);
107 if (pchRequest != NULL) HeapFree(hHeap, 0, pchRequest);
108 return (DWORD)-1;
109 }
110
111 if (pchRequest == NULL)
112 {
113 printf( "\nERROR - Pipe Server Failure:\n");
114 printf( " InstanceThread got an unexpected NULL heap allocation.\n");
115 printf( " InstanceThread exitting.\n");
116 if (pchReply != NULL) HeapFree(hHeap, 0, pchReply);
117 return (DWORD)-1;
118 }
119
120 if (pchReply == NULL)
121 {
122 printf( "\nERROR - Pipe Server Failure:\n");
123 printf( " InstanceThread got an unexpected NULL heap allocation.\n");
124 printf( " InstanceThread exitting.\n");
125 if (pchRequest != NULL) HeapFree(hHeap, 0, pchRequest);
126 return (DWORD)-1;
127 }
128
129 // Print verbose messages. In production code, this should be for debugging only.
130 printf("InstanceThread created, receiving and processing messages.\n");
131
132 // The thread‘s parameter is a handle to a pipe object instance.
133
134 hPipe = (HANDLE) lpvParam;
135
136 // Loop until done reading
137 while (1)
138 {
139 // Read client requests from the pipe. This simplistic code only allows messages
140 // up to BUFSIZE characters in length.
141 fSuccess = ReadFile(
142 hPipe, // handle to pipe
143 pchRequest, // buffer to receive data
144 BUFSIZE*sizeof(TCHAR), // size of buffer
145 &cbBytesRead, // number of bytes read
146 NULL); // not overlapped I/O
147
148 if (!fSuccess || cbBytesRead == 0)
149 {
150 if (GetLastError() == ERROR_BROKEN_PIPE)
151 {
152 _tprintf(TEXT("InstanceThread: client disconnected.\n"), GetLastError());
153 }
154 else
155 {
156 _tprintf(TEXT("InstanceThread ReadFile failed, GLE=%d.\n"), GetLastError());
157 }
158 break;
159 }
160
161 // Process the incoming message.
162 GetAnswerToRequest(pchRequest, pchReply, &cbReplyBytes);
163
164 // Write the reply to the pipe.
165 fSuccess = WriteFile(
166 hPipe, // handle to pipe
167 pchReply, // buffer to write from
168 cbReplyBytes, // number of bytes to write
169 &cbWritten, // number of bytes written
170 NULL); // not overlapped I/O
171
172 if (!fSuccess || cbReplyBytes != cbWritten)
173 {
174 _tprintf(TEXT("InstanceThread WriteFile failed, GLE=%d.\n"), GetLastError());
175 break;
176 }
177 }
178
179 // Flush the pipe to allow the client to read the pipe‘s contents
180 // before disconnecting. Then disconnect the pipe, and close the
181 // handle to this pipe instance.
182
183 FlushFileBuffers(hPipe);
184 DisconnectNamedPipe(hPipe);
185 CloseHandle(hPipe);
186
187 HeapFree(hHeap, 0, pchRequest);
188 HeapFree(hHeap, 0, pchReply);
189
190 printf("InstanceThread exitting.\n");
191 return 1;
192 }
193
194 VOID GetAnswerToRequest( LPTSTR pchRequest,
195 LPTSTR pchReply,
196 LPDWORD pchBytes )
197 // This routine is a simple function to print the client request to the console
198 // and populate the reply buffer with a default data string. This is where you
199 // would put the actual client request processing code that runs in the context
200 // of an instance thread. Keep in mind the main thread will continue to wait for
201 // and receive other client connections while the instance thread is working.
202 {
203 _tprintf( TEXT("Client Request String:\"%S\"\n"), pchRequest );//这里注意大小写的%S,见上一篇随笔
204
205 // Check the outgoing message to make sure it‘s not too long for the buffer.
206 if (FAILED(StringCchCopy( pchReply, BUFSIZE, TEXT("default answer from server") )))
207 {
208 *pchBytes = 0;
209 pchReply[0] = 0;
210 printf("StringCchCopy failed, no outgoing message.\n");
211 return;
212 }
213 *pchBytes = (lstrlen(pchReply)+1)*sizeof(TCHAR);
214 }

客户端:


// client.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>

#define BUFSIZE 512

int _tmain(int argc, TCHAR *argv[])
{
HANDLE hPipe;
LPTSTR lpvMessage=TEXT("Default message from client.");
TCHAR chBuf[BUFSIZE];
BOOL fSuccess = FALSE;
DWORD cbRead, cbToWrite, cbWritten, dwMode;
LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");

if( argc > 1 )
lpvMessage = argv[1];

// Try to open a named pipe; wait for it, if necessary.

while (1)
{
hPipe = CreateFile(
lpszPipename, // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL); // no template file

// Break if the pipe handle is valid.

if (hPipe != INVALID_HANDLE_VALUE)
break;

// Exit if an error other than ERROR_PIPE_BUSY occurs.

if (GetLastError() != ERROR_PIPE_BUSY)
{
_tprintf( TEXT("Could not open pipe. GLE=%d\n"), GetLastError() );
return -1;
}

// All pipe instances are busy, so wait for 20 seconds.

if ( ! WaitNamedPipe(lpszPipename, 20000))
{
printf("Could not open pipe: 20 second wait timed out.");
return -1;
}
}

// The pipe connected; change to message-read mode.

dwMode = PIPE_READMODE_MESSAGE;
fSuccess = SetNamedPipeHandleState(
hPipe, // pipe handle
&dwMode, // new pipe mode
NULL, // don‘t set maximum bytes
NULL); // don‘t set maximum time
if ( ! fSuccess)
{
_tprintf( TEXT("SetNamedPipeHandleState failed. GLE=%d\n"), GetLastError() );
return -1;
}

// Send a message to the pipe server.

cbToWrite = (lstrlen(lpvMessage)+1)*sizeof(TCHAR);
_tprintf( TEXT("Sending %d byte message: \"%s\"\n"), cbToWrite, lpvMessage);

fSuccess = WriteFile(
hPipe, // pipe handle
lpvMessage, // message
cbToWrite, // message length
&cbWritten, // bytes written
NULL); // not overlapped

if ( ! fSuccess)
{
_tprintf( TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError() );
return -1;
}

printf("\nMessage sent to server, receiving reply as follows:\n");

do
{
// Read from the pipe.

fSuccess = ReadFile(
hPipe, // pipe handle
chBuf, // buffer to receive reply
BUFSIZE*sizeof(TCHAR), // size of buffer
&cbRead, // number of bytes read
NULL); // not overlapped

if ( ! fSuccess && GetLastError() != ERROR_MORE_DATA )
break;

_tprintf( TEXT("\"%S\"\n"), chBuf );
} while ( ! fSuccess); // repeat loop if ERROR_MORE_DATA

if ( ! fSuccess)
{
_tprintf( TEXT("ReadFile from pipe failed. GLE=%d\n"), GetLastError() );
return -1;
}

printf("\n<End of message, press ENTER to terminate connection and exit>");
_getch();

CloseHandle(hPipe);

return 0;
}

命名管道-MSDN例子

时间: 2024-11-08 22:15:28

命名管道-MSDN例子的相关文章

linux进程通信之命名管道

前一节学习了无名管道,这节学习命名管道. 二命名管道 无名管道只能用来在父子进程或兄弟进程之间进行通信,这就给没有亲缘关系的进程之间数据的交换带来了麻烦,解决这个问题就是本节要学习的另一种管道通信:命名管道. 命名管道也被称为FIFO文件,FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中.这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIF

命名管道-简单的例子

#include "stdafx.h" #include<iostream> #include<windows.h> #include<ctime> using namespace std; DWORD WINAPI thread1(LPVOID param) { char buf[256]; DWORD rlen=0; HANDLE hPipe = CreateNamedPipe(TEXT("\\\\.\\Pipe\\mypipe&quo

Linux进程间通信 -- 使用命名管道

在前一篇文章—— Linux进程间通信 -- 使用匿名管道 中,我们看到了如何使用匿名管道来在进程之间传递数据,同时也看到了这个方式的一个缺陷,就是这些进程都由一个共同的祖先进程启动,这给我们在不相关的的进程之间交换数据带来了不方便.这里将会介绍进程的另一种通信方式——命名管道,来解决不相关进程间的通信问题. 一.什么是命名管道 命名管道也被称为FIFO文件,它是一种特殊类型的文件,它在文件系统中以文件名的形式存在,但是它的行为却和之前所讲的没有名字的管道(匿名管道)类似. 由于Linux中所有

进程间通信(5) - 命名管道(FIFO)

1. 前言 本篇文章的所有例子,基于RHEL6.5平台.前一篇文章介绍了匿名管道.点此链接. 2.介绍 管道应用的一个重大限制是它没有名字,因此,只能用于具有亲缘关系的进程间通信,在有名管道(named pipe或FIFO)提出后,该限制得到了克服.FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中.这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,

c++下使用命名管道实现进程间通信

前面已经使用邮槽实现过进程间通信:http://www.cnblogs.com/jzincnblogs/p/5192654.html ,这里使用命名管道实现进程间通信. 与邮槽不同的是,命名管道在进程间传输数据是基于连接且可靠的传输方式,所以命名管道传输数据只能一对一.使用命名管道的步骤如下: ①创建命名管道,命名管道通过调用函数CreateNamedPipe()创建,函数原型如下: 1 HANDLE WINAPI CreateNamedPipe( 2 _In_ LPCTSTR lpName,

命名管道跨进程通信实例1(转)

原文地址:http://www.cnblogs.com/yukaizhao/archive/2011/08/08/namedpipeserverstream-example.html 本文介绍命名管道使用实例,文中例子是几个客户端都通过一台服务器获得新生成的int类型id. 服务器端功能:当客户端请求一个新的id时,将现有id自增1,然后返回给客户端. 服务器端实现:在程序启动时,启动n个线程,在每个线程中都声明一个NamedPipeServerStream的实例,并循环的WaitForConn

进程间的通信——邮槽与命名管道d

进程间的通信是指在系统中两个或多个进程之间通过第三方进行数据共享. 1.邮槽. 邮槽是window系统提供的一种单向通信的机制.即进程中的一方只能写入或者读取数据,而另一方则只能读取或写入数据.通过邮槽,可以实现一对多或跨网络的进程之间的通信.但邮槽传输的数据量非常小,一般只有400KB左右. 邮槽创建函数CreateMailslot,函数原型: HANDLE CreateMailslot( LPCTSTR lpName, // mailslot name DWORD nMaxMessageSi

IPC——命名管道

Linux进程间通信——使用命名管道 转载:http://blog.csdn.net/ljianhui/article/details/10202699 在前一篇文章——Linux进程间通信——使用匿名管道中,我们看到了如何使用匿名管道来在进程之间传递数据,同时也看到了这个方式的一个缺陷,就是这些进程都由一个共同的祖先进程启动,这给我们在不相关的的进程之间交换数据带来了不方便.这里将会介绍进程的另一种通信方式——命名管道,来解决不相关进程间的通信问题. 一.什么是命名管道 命名管道也被称为FIF

SQL Server 连接问题-命名管道

原文:SQL Server 连接问题-命名管道 出自:http://blogs.msdn.com/b/apgcdsd/archive/2011/01/12/sql-server-1.aspx 一.前言 在使用SQL Server 的过程中,用户遇到的最多的莫过于连接问题了.本文将深度讨论SQL Server 连接问题的方方面面,希望能帮你彻底解决SQL server 的连接问题. SQL Server 支持的通讯协议很多,如命名管道(Named Pipes).TCP/IP 套接字.共享内存(Sh