0

パイプの例という名前のウィンドウを使用しています。サンプル プログラムを実行してパイプを作成し、何かを記述し、それをクライアント プログラムで受信すると、すべて問題ありません。Windows サービスで実行されるクライアント コードを dll に移動すると、送信されたバイトが受信されません。

サーバーのコードは次のとおりです。

ThreadParams * params = reinterpret_cast<ThreadParams*>(args);
CString * connectionString = params->connectString;

HANDLE hPipe;
DWORD dwBytesRead;
TCHAR buf[1024];
int len;

hPipe = CreateNamedPipe(PIPE_NAME,  // Name
                        PIPE_ACCESS_OUTBOUND | WRITE_OWNER, // OpenMode
                        PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, // PipeMode
                        2, // MaxInstances
                        1024, // OutBufferSize
                        1024, // InBuffersize
                        2000, // TimeOut
                        NULL); // Security
if (hPipe == INVALID_HANDLE_VALUE)
{
    Globals::WriteLog("Could not create the pipe",1);
    exit(1);
}

Globals::WriteLog("connect...",1);
ConnectNamedPipe(hPipe, NULL);
Globals::WriteLog("...connected",1);

swprintf(buf, connectionString->GetBuffer());
len = wcslen(buf);

if (!WriteFile(hPipe, buf, len*sizeof(TCHAR), &dwBytesRead, NULL))
    Globals::WriteLog("WriteFile failed",1);
else
    wprintf(L"written %d bytes\n",dwBytesRead);

DisconnectNamedPipe(hPipe);

CloseHandle(hPipe);

クライアント:

    CString finalResult = _T("");

HANDLE      hOut = INVALID_HANDLE_VALUE;
TCHAR       buf[1024];
DWORD       len;
DWORD       dwWritten;

Global::WriteLog("pwrite: waiting for the pipe...",1);
if (WaitNamedPipe(PIPE_NAME, NMPWAIT_WAIT_FOREVER) == 0)
{
    Global::WriteLog("WaitNamedPipe failed. error=%d",1,GetLastError());
    goto cleanup;
}
Global::WriteLog("the pipe is ready",1);

hOut = CreateFile(PIPE_NAME,
    GENERIC_READ,
    0,
    NULL, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);
if (hOut == INVALID_HANDLE_VALUE)
{
    Global::WriteLog("CreateFile failed with error %d",1,GetLastError());
    goto cleanup;
}
Global::WriteLog("Opened the pipe",1);

for (;;)
{
    if (!ReadFile(hOut, buf, sizeof(buf), &dwWritten, NULL))
    {
        Global::WriteLog("ReadFile failed -- probably EOF. Read %d bytes.",1,dwWritten);
        goto cleanup;
    }
    else
        break;
}

finalResult = CString(buf);
Global::WriteLog("String from pipe:%S",1,buf);
cleanup:
if(hOut != INVALID_HANDLE_VALUE)
    CloseHandle(hOut);

何か変更があった場合、サーバーのコードはスレッドで実行されます (サンプル プログラムでこのスレッド バージョンでテストしましたが、問題はありませんでした)。

うまくいかないのはなぜですか?

前もって感謝します

4

1 に答える 1

1

わかりました、私はそれを理解したようです。ドキュメントを正しく理解していなかったようです。

サーバー側の WriteFile 関数は、文字列が読み取られるまでブロックされません。私のプログラムは単にデータを書き込んでからハンドルを閉じました-パイプ。クライアントはメッセージをキャッチせず、パイプの反対側にプロセスがないことを示すエラーをスローしました。

また、クライアントから for(;;) ループを削除しました。

クライアント側での読み取り操作が完了するのを待つために、追加しました

FlushFileBuffers(hPipe);

書き込み操作が成功した後。

誰かを助けることを願っています

于 2012-10-24T15:50:03.733 に答える