进程间命名管道通信有关问题

进程间命名管道通信问题
服务端代码:
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;
}