进程间命名管道通信有关问题
进程间命名管道通信问题
服务端代码:
客户端代码:
服务端代码:
- C/C++ code
#include <Windows.h> #include "resource.h" //===================函数声明===================== DWORD WINAPI ThreadProc(LPVOID lParam); BOOL CALLBACK MainDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); //===================全局数据====================== #define BUFFERSIZE 4096 TCHAR *szPipeName = TEXT("\\\\.\\pipe\\testPipe"); TCHAR *szPipeIdentity = TEXT("I am the true server"); HWND hWinMain; TCHAR szBuffer[BUFFERSIZE]; TCHAR szFileName[MAX_PATH + 3]; //===================主函数==================== INT_PTR WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_MAINDLG), NULL, MainDlg, NULL); return 0; } //====================对话框函数========================= BOOL CALLBACK MainDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static DWORD dwThreadID; switch(message) { case WM_INITDIALOG: hWinMain = hDlg; CreateThread(NULL, 0, ThreadProc, NULL, NULL, &dwThreadID); return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_CLOSE: SendMessage(hDlg, WM_CLOSE, NULL, NULL); break; } return TRUE; case WM_CLOSE: EndDialog(hDlg, TRUE); return TRUE; } return FALSE; } //================线程函数========================= // 实现创建管道,连接,显示状态等功能 DWORD WINAPI ThreadProc(LPVOID lParam) { static DWORD dwNumberOfByteWritten; static DWORD dwNumberOfByteRead; //----------------------创建管道------------------------------- HANDLE hNamedPipe = CreateNamedPipe(szPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFFERSIZE, BUFFERSIZE, NMPWAIT_USE_DEFAULT_WAIT, NULL); if(hNamedPipe == INVALID_HANDLE_VALUE) { MessageBox(hWinMain, TEXT("命名管道创建失败"), NULL, MB_OK); return 1; } //-----------------------连接管道------------------------------- if(ConnectNamedPipe(hNamedPipe, NULL)) { SetDlgItemText(hWinMain, IDC_STATE, TEXT("已连接")); } else { SetDlgItemText(hWinMain, IDC_STATE, TEXT("连接失败,请关闭重试")); return 1; } //-----------------------使用管道---------------------------------- //写入服务器身份信息 WriteFile(hNamedPipe, szPipeIdentity, lstrlen(szPipeIdentity) + 1, &dwNumberOfByteWritten, NULL); //读出客户端传来的文件名 ReadFile(hNamedPipe, szFileName, lstrlen(szFileName) + 1, &dwNumberOfByteRead, NULL); //lstrcpy(szFileName, TEXT("d:\\textfile.txt"));//temp //打开文件 HANDLE hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile == INVALID_HANDLE_VALUE) { SetDlgItemText(hWinMain, IDC_FILENAME, TEXT("打开文件失败,请关闭重试")); } else { lstrcat(szFileName, TEXT("已打开")); SetDlgItemText(hWinMain, IDC_FILENAME, szFileName); } //读取文件内容并写入管道 while(ReadFile(hFile, szBuffer, 4096, &dwNumberOfByteRead, NULL) && dwNumberOfByteRead) { WriteFile(hNamedPipe, szBuffer, dwNumberOfByteRead, &dwNumberOfByteWritten, NULL); } CloseHandle(hNamedPipe); CloseHandle(hFile); return 0; }
客户端代码:
- C/C++ code
#include "resource.h" #include <Windows.h> //=================函数声明=========================== BOOL CALLBACK MainDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); DWORD WINAPI ThreadProc(LPVOID lParam); //=================全局数据========================= HWND hWinMain; #define BUFFERSIZE 4096 TCHAR *szPipeName = TEXT("\\\\.\\pipe\\testPipe"); TCHAR *szPipeIdentity = TEXT("I am the true server"); TCHAR *szFileName = TEXT("d:\\textfile.txt"); TCHAR szBuffer[BUFFERSIZE]; //==================主函数================================ int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd ) { DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_MAINDLG), NULL, MainDlg, NULL); return 0; } //====================窗口函数=================================== BOOL CALLBACK MainDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: hWinMain = hDlg; CreateThread(NULL, 0, ThreadProc, NULL, NULL, NULL); return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_CLOSE: SendMessage(hDlg, WM_CLOSE, NULL, NULL); break; } return TRUE; case WM_CLOSE: EndDialog(hDlg, TRUE); return TRUE; } return FALSE; } //=====================线程函数================== DWORD CALLBACK ThreadProc (LPVOID lParam) { static DWORD dwNumberOfByteWritten; static DWORD dwNumberOfByteRead; //---------------打开并连接管道----------------------------- HANDLE hNamedPipe = CreateFile(szPipeName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hNamedPipe == INVALID_HANDLE_VALUE) { SetDlgItemText(hWinMain, IDC_STATE, TEXT("打开、连接管道失败,请关闭重试")); return FALSE; } //-----------------获取服务器身份信息-------------------------------- ReadFile(hNamedPipe, szBuffer, BUFFERSIZE, &dwNumberOfByteRead, NULL); if(lstrcmp(szBuffer, szPipeIdentity)) { SetDlgItemText(hWinMain, IDC_STATE, TEXT("已连接")); } else { SetDlgItemText(hWinMain, IDC_STATE, TEXT("未成功连接服务器")); return FALSE; } //-----------------向管道写入文件名------------------------------ WriteFile(hNamedPipe, szFileName, lstrlen(szFileName) + 1, &dwNumberOfByteWritten, NULL); SetDlgItemText(hWinMain, IDC_FILENAME, szFileName); EnableWindow(GetDlgItem(hWinMain, IDC_FILETEXT), TRUE); while(ReadFile(hNamedPipe, szBuffer, BUFFERSIZE, &dwNumberOfByteRead, NULL) && dwNumberOfByteRead) { SendDlgItemMessage(hWinMain, IDC_FILETEXT, EM_SETSEL, -1, -1); SendDlgItemMessage(hWinMain, IDC_FILETEXT, EM_REPLACESEL, FALSE, (LPARAM)szBuffer); } return TRUE; }