非I/0的有名管道(包括服务器和客户端)

本文提供了一个使用Windows管道进行客户端与服务器间通信的C++示例程序。该程序详细展示了如何创建并使用命名管道实现双向消息传递,包括服务器端接收请求、处理请求并回复客户端的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

服务器端:

 #include "stdafx.h"
#include "windows.h"
#include <iostream>
using namespace std;
 #define BUFSIZE 4096
VOID GetAnswerToRequest(char* chRequest,
   char* chReply, LPDWORD pchBytes);
 DWORD WINAPI ChildThread( LPARAM lparam )
 {
    char chRead[BUFSIZE];
 char chReply[BUFSIZE];
 DWORD cbRead=0, cbWritten=0, cbReplyBytes=0;
 HANDLE hPipeDup = (HANDLE) lparam;
 BOOL fSuccess;
 
 while(1)
 {
  fSuccess=ReadFile(
   hPipeDup,
   chRead,
   BUFSIZE*sizeof(char),
   &cbRead ,
   NULL);
  if( !fSuccess || cbRead == 0 )
  {
   cout<<endl;
   cout<<"ReadFile Error:"<<GetLastError()<<endl;
   break;
  }
  GetAnswerToRequest(chRead, chReply, &cbWritten);
  // Write the reply to the pipe.
  fSuccess = WriteFile(
    hPipeDup,   // handle to pipe
    chReply,   // buffer to write from
    cbWritten,   // number of bytes to write
    &cbReplyBytes,  // number of bytes written
    NULL);    // not overlapped I/O

  if (! fSuccess || cbReplyBytes != cbWritten)
  {
   cout<<"WriteFile Error:"<<GetLastError()<<endl;
   break;
  }
  printf( "WriteFile success!:%d:%d/n",cbReplyBytes,cbWritten );
 }
 // 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(hPipeDup);
   DisconnectNamedPipe(hPipeDup);
   CloseHandle(hPipeDup);
   return 1;
 }
int _tmain(int argc, _TCHAR* argv[])
{
 DWORD bytesRead = 0;
 HANDLE hPipe = CreateNamedPipe(
  _T("////.//pipe//mypipe"),
  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
  NMPWAIT_USE_DEFAULT_WAIT, // client time-out
  NULL);                    // default security attribute 
 if( hPipe == INVALID_HANDLE_VALUE )
 {
  cout<<"create pipe don't success!:"<<GetLastError()<<endl;
  ExitProcess( 1 );
 }
 //get server address
 HANDLE hPipeDup = NULL;
    BOOL fSuccess = DuplicateHandle(GetCurrentProcess(), hPipe,
      GetCurrentProcess(), &hPipeDup , 0,
      FALSE,
      DUPLICATE_SAME_ACCESS);
 if( !fSuccess )
 {
  cout<<"duplicate pipe don't success!:"<<GetLastError()<<endl;
  ExitProcess( 1 );
 }
 BOOL ret = ConnectNamedPipe( hPipeDup , NULL );
 if( ret == FALSE  )
  {
  if( GetLastError() == ERROR_PIPE_CONNECTED )
   {
    cout<<"client had been connected to pipe!"<<endl;
   }
  else
  {
   cout<<"connect error:"<<GetLastError()<<endl;
   ExitProcess( 1 );
  }
  }
  else
  {
   cout<<"client is connected to named pipe:"<<endl;
  }
 HANDLE hThread = CreateThread( NULL , 0 , (LPTHREAD_START_ROUTINE)ChildThread , (LPVOID)hPipe ,CREATE_SUSPENDED ,NULL );
 if( hThread != NULL )
 {
  ResumeThread( hThread );
 }
 else
 {
  cout<< "create child thread failure:"<< GetLastError() <<endl;
  ExitProcess( 1 );
 }
 cout<<"please input any key to exit!"<<endl;
 int iii;
 cin>>iii;
 CloseHandle( hThread );
 CloseHandle( hPipe );
 CloseHandle( hPipeDup );
 return 0;
}
VOID GetAnswerToRequest(char* chRequest,
   char* chReply, LPDWORD pchBytes)
{
   printf( "%s/n", chRequest );
   strcpy( chReply, "Default answer from server" );
   *pchBytes = (strlen(chReply)+1)*sizeof(char);
}
客户端代码:

#include "stdafx.h"
#include <windows.h>
#include <conio.h>
#define BUFSIZE 512


int _tmain(int argc, _TCHAR* argv[])
{
   HANDLE hPipe = NULL;
   LPTSTR lpvMessage=TEXT("Default message from client");
   char chBuf[BUFSIZE];
   BOOL fSuccess;
   DWORD cbRead, cbWritten, dwMode;
   //LPTSTR lpszPipename = TEXT("////.//pipe//mypipe");
   char *lpszPipename = "////.//pipe//mypipe";

   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;
   }
// 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(char),  // size of buffer
         &cbRead,  // number of bytes read
         NULL);    // not overlapped
 
      if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
         break;
   chBuf[cbRead] = '/0';
   _tprintf( TEXT("%s:%d/n"), chBuf ,cbRead );
   } while (!fSuccess);  // repeat loop if ERROR_MORE_DATA

   _getch();
 
   CloseHandle(hPipe);
 
   return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值