可以实现多客户端对一服务端,服务端为客户端提供服务。
其实一服务端对应每一个client pipe都新建立了一个pipe。windows允许建立多个同名pipe
效果:
服务端代码:
#define BUFSIZE 2048 unsigned __stdcall MsgProcessThread ( void * pParam) { HANDLE hPipe = (HANDLE)pParam; while(1) { char szBufRecv[1024] = {0}; DWORD dwReadSize = 0; cout<<"服务端准备读消息.."<<endl; BOOL bRet = ::ReadFile(hPipe,szBufRecv,1024,&dwReadSize,NULL); if(!bRet || dwReadSize == 0) { DWORD dwLastError = ::GetLastError(); if(dwLastError == ERROR_BROKEN_PIPE) cout<<"断开连接!"<<endl; else cout<<"ReadFile Error:"<<dwLastError<<endl; break; } else { cout<<"服务器收到"<<dwReadSize<<"字节:"<<szBufRecv<<endl; string srouce_str,a1,a2,str_sum; srouce_str = szBufRecv; [srouce_str,&a1,&a2,&str_sum](){ auto pos_flag = srouce_str.find("+"); if(pos_flag != string::npos) { a1 = srouce_str.substr(0,pos_flag); a2 = srouce_str.substr(pos_flag+1); int add_value1 = atoi(a1.c_str()); int add_value2 = atoi(a2.c_str()); int sum = add_value1 + add_value2; char szTemp[100]; _itoa_s(sum,szTemp,100,10); str_sum = szTemp; } }(); DWORD dwWritten = 0; bRet = WriteFile(hPipe,str_sum.c_str(),str_sum.length() + 1,&dwWritten,NULL); if(!bRet) { int nError = ::GetLastError(); cout<<"服务器WriteFile失败,errorid:"<<nError<<endl; break; } else if(dwWritten == 0) { cout<<"服务器WriteFile失败,发送字节为0"<<endl; break; } } } CloseHandle(hPipe); return 0; } int _tmain(int argc, _TCHAR* argv[]) { HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL; const char * lpszPipename = ("\\\\.\\pipe\\namedpipe_td"); for (;;) { hPipe = CreateNamedPipeA( lpszPipename, PIPE_ACCESS_DUPLEX,PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,BUFSIZE,BUFSIZE,0,NULL); if (hPipe == INVALID_HANDLE_VALUE) return -1; BOOL fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); if(fConnected) { CloseHandle((HANDLE)_beginthreadex(NULL,0,MsgProcessThread,(void*)hPipe,0,NULL)); } else CloseHandle(hPipe); } system("puase"); return 0; }
客户端代码
#include "stdafx.h" #include <iostream> using namespace std; #include <windows.h> #include <time.h> int _tmain(int argc, _TCHAR* argv[]) { HANDLE hPipe = []()->HANDLE { while(1) { HANDLE hPipe = CreateFileA( "\\\\.\\pipe\\namedpipe_td",GENERIC_READ | GENERIC_WRITE, 0,NULL,OPEN_EXISTING,0, NULL); if(hPipe != INVALID_HANDLE_VALUE) { cout<<"open pipe success!"<<endl; return hPipe; } int nErrorId = GetLastError(); if(nErrorId != ERROR_PIPE_BUSY) { cout<<"client createfile error :"<<nErrorId<<endl; return NULL; } cout<<"WaitNamedPipeA ..."<<endl; if(!WaitNamedPipeA("\\\\.\\pipe\\namedpipe_td",10000)) { if(GetLastError() == ERROR_SEM_TIMEOUT) cout<<"WaitNamePipeA timeOut!"<<endl; else { cout<<"WaitNamePipeA Failed:"<<GetLastError()<<endl; break; } } else { cout<<"waitNamedPipe success!"<<endl; continue; } } return NULL; }(); if(hPipe == INVALID_HANDLE_VALUE || !hPipe) { cout<<"connect server failed!"<<endl; system("pause"); return 0; } cout<<"连接成功!"<<endl; DWORD dwMode = PIPE_READMODE_MESSAGE; if(!SetNamedPipeHandleState(hPipe,&dwMode,NULL,NULL)) { cout<<"SetNamedPipeHandleState failed!"<<endl; system("pause"); return 0; } while (true) { char send_buff[256] = {0}; int a1 = rand() % 100; int a2 = rand() % 100; sprintf_s(send_buff,"%d+%d",a1,a2); DWORD dwWritten = 0; if(!WriteFile(hPipe,send_buff,strlen(send_buff)+1,&dwWritten,NULL)) { int nLastError = ::GetLastError(); if(ERROR_NO_DATA == nLastError) cout<<"pipi already closeed!"<<endl; else cout<<"client writefile failed:"<<nLastError<<endl; system("pause"); return 0; } if(dwWritten == 0) { cout<<"client writefile failed dwWritten = 0"<<endl; system("pause"); return 0; } char buffer_readed[256] = {0}; DWORD dwReaded = 0; Sleep(10); if(!ReadFile(hPipe,buffer_readed,256,&dwReaded,NULL)) { int nLastError = ::GetLastError(); if(ERROR_NO_DATA == nLastError) cout<<"pipi already closeed!"<<endl; else cout<<"client ReadFile failed:"<<nLastError<<endl; system("pause"); return 0; } if(dwReaded == 0) { cout<<"client ReadFile failed:dwReaded == 0"<<endl; system("pause"); return 0; } char szBuff[256] = {0}; int nSum = atoi(buffer_readed); if(nSum != a1 + a2) cout<<"!!错误"<<endl; sprintf_s(szBuff,"%d+%d=%s",a1,a2,buffer_readed); cout<<szBuff<<endl; } return 0; }