设为首页 收藏本站
查看: 2043|回复: 0

[经验分享] Windows进程间通信—命名管道

[复制链接]

尚未签到

发表于 2017-6-27 16:24:21 | 显示全部楼层 |阅读模式
  命名管道是通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节。我们在不了解网络协议的情况下,也可以利用命名管道来实现进程间的通信。与Socket网络通信相比,命名管道不再需要编写身份验证的代码。将命名管道作为一种网络编程方案时,它实际上建立了一个C/S通信体系,并在其中可靠的传输数据。命名管道服务器和客户机的区别在于:服务器是唯一一个有权创建命名管道的进程,也只有它能接受管道客户机的连接请求。而客户机只能同一个现成的命名管道服务器建立连接。命名管道服务器只能在WindowsNT或Windows2000上创建,不过可以是客户机。命名管道提供了两种基本通信模式,字节模式和消息模式。在字节模式中,数据以一个连续的字节流的形式在客户机和服务器之间流动。而在消息模式中,客户机和服务器则通过一系列不连续的数据单位进行数据的收发,每次在管道上发出一条消息后,它必须作为一条完整的消息读入。
  服务端代码流程:
  1、创建命名管道:CreateNamedPipe
  2、等待客户端连接:ConnectNamedPipe
  3、读取客户端请求数据:ReadFile
  4、向客户端回复数据:WriteFile
  5、关闭连接:DisconnectNamedPipe
  6、关闭管道:CloseHandle



#include "stdafx.h"  
#include <windows.h>  
#include <strsafe.h>  
#define BUFSIZE 4096  
DWORD WINAPI InstanceThread(LPVOID);   
VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD);   
int _tmain(VOID)   
{   
BOOL fConnected;   
DWORD dwThreadId;   
HANDLE hPipe, hThread;   
LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");   
// The main loop creates an instance of the named pipe and   
// then waits for a client to connect to it. When the client   
// connects, a thread is created to handle communications   
// with that client, and the loop is repeated.   
for (;;)   
{   
hPipe = CreateNamedPipe(   
lpszPipename,             // pipe name   
PIPE_ACCESS_DUPLEX,       // read/write access   
PIPE_TYPE_MESSAGE |       // message type pipe   
PIPE_READMODE_MESSAGE |   // message-read mode   
PIPE_WAIT,                // blocking mode   
PIPE_UNLIMITED_INSTANCES, // max. instances   
BUFSIZE,                  // output buffer size   
BUFSIZE,                  // input buffer size   
0,                        // client time-out   
NULL);                    // default security attribute   
if (hPipe == INVALID_HANDLE_VALUE)   
{  
printf("CreatePipe failed");   
return 0;  
}  
// Wait for the client to connect; if it succeeds,   
// the function returns a nonzero value. If the function  
// returns zero, GetLastError returns ERROR_PIPE_CONNECTED.   
  
fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);   
if (fConnected)   
{   
// Create a thread for this client.   
hThread = CreateThread(   
NULL,              // no security attribute   
0,                 // default stack size   
InstanceThread,    // thread proc  
(LPVOID) hPipe,    // thread parameter   
0,                 // not suspended   
&dwThreadId);      // returns thread ID   
if (hThread == NULL)   
{  
printf("CreateThread failed");   
return 0;  
}  
else CloseHandle(hThread);   
}   
else  
{  
// The client could not connect, so close the pipe.   
            CloseHandle(hPipe);   
}  
}   
return 1;   
}   
DWORD WINAPI InstanceThread(LPVOID lpvParam)   
{   
TCHAR chRequest[BUFSIZE];   
TCHAR chReply[BUFSIZE];   
DWORD cbBytesRead, cbReplyBytes, cbWritten;   
BOOL fSuccess;   
HANDLE hPipe;   
// The thread's parameter is a handle to a pipe instance.   
  
hPipe = (HANDLE) lpvParam;   
while (1)   
{   
// Read client requests from the pipe.   
fSuccess = ReadFile(   
hPipe,        // handle to pipe   
chRequest,    // buffer to receive data   
BUFSIZE*sizeof(TCHAR), // size of buffer   
&cbBytesRead, // number of bytes read   
NULL);        // not overlapped I/O   
if (! fSuccess || cbBytesRead == 0)   
break;   
printf((const char*)chRequest);  
GetAnswerToRequest(chRequest, chReply, &cbReplyBytes);   
// Write the reply to the pipe.   
fSuccess = WriteFile(   
hPipe,        // handle to pipe   
chReply,      // buffer to write from   
cbReplyBytes, // number of bytes to write   
&cbWritten,   // number of bytes written   
NULL);        // not overlapped I/O   
if (! fSuccess || cbReplyBytes != cbWritten) break;   
}   
// Flush the pipe to allow the client to read the pipe's contents   
// before disconnecting. Then disconnect the pipe, and close the   
// handle to this pipe instance.   
  
FlushFileBuffers(hPipe);   
DisconnectNamedPipe(hPipe);   
CloseHandle(hPipe);   
return 1;  
}  
VOID GetAnswerToRequest(LPTSTR chRequest,   
LPTSTR chReply, LPDWORD pchBytes)  
{  
_tprintf( TEXT("%s\n"), chRequest );  
StringCchCopy( chReply, BUFSIZE, TEXT("Default answer from server") );  
*pchBytes = (lstrlen(chReply)+1)*sizeof(TCHAR);  
}  
/* 何问起 hovertree.com */
  客户端代码流程:
  1、打开命名管道:CreateFile
  2、等待服务端响应:WaitNamedPipe
  3、切换管道为读模式:SetNamedPipeHandleState
  4、向服务端发数据:WriteFile
  5、读服务端返回的数据:ReadFile
  6、关闭管道:CloseHandle



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

#define BUFSIZE 512  
int _tmain(int argc, TCHAR *argv[])   
{   
HANDLE hPipe;   
LPTSTR lpvMessage=TEXT("Default message from client");   
TCHAR chBuf[BUFSIZE];   
BOOL fSuccess;   
DWORD cbRead, 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)   
{  
printf("Could not open pipe");   
return 0;  
}  
// All pipe instances are busy, so wait for 20 seconds.   
if (!WaitNamedPipe(lpszPipename, 20000))   
{   
printf("Could not open pipe");   
return 0;  
}   
}   
// 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)   
{  
printf("SetNamedPipeHandleState failed");   
return 0;  
}  // 何问起 hovertree.com
// Send a message to the pipe server.   
  
fSuccess = WriteFile(   
hPipe,                  // pipe handle   
lpvMessage,             // message   
(lstrlen(lpvMessage)+1)*sizeof(TCHAR), // message length   
&cbWritten,             // bytes written   
NULL);                  // not overlapped   
if (!fSuccess)   
{  
printf("WriteFile failed");   
return 0;  
}  
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   
  
getch();  
CloseHandle(hPipe);   
return 0;   
}  
  推荐:http://www.cnblogs.com/roucheng/p/vs2015cpp.html

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-388819-1-1.html 上篇帖子: windows中的进程和线程 下篇帖子: Windows安装MySQL5.7.17
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表