Windows进程间通信—命名管道

命名管道是通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节。我们在不了解网络协议的情况下,也可以利用命名管道来实现进程间的通信。与Socket网络通信相比,命名管道不再需要编写身份验证的代码。将

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

命名管道是通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节。我们在不了解网络协议的情况下,也可以利用命名管道来实现进程间的通信。与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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/120294.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号