命名管道在后台等待客户端,直到客户端连接

Posted

技术标签:

【中文标题】命名管道在后台等待客户端,直到客户端连接【英文标题】:Named pipe wait for client in background until client connects 【发布时间】:2014-04-15 08:33:47 【问题描述】:

我试图让我的命名管道服务器跳过 ConnectNamedPipe 函数的块等待,直到我的客户端尝试连接。所以我想让我的代码继续通过 ConnetNamedPipe 行直到结束,但在后台保持我的管道连接打开。如果我在创建管道时使用 PIPE_NOWAIT 模式,它只会立即返回,并且管道会在我的客户端连接之前关闭。

我知道我尝试使用线程执行此操作,但即使我创建线程并在线程中执行代码的 ConnectNamedPipe 部分,它仍会在此行等待,而不是继续执行我的代码。一旦它到达我的服务器 cpp 文件代码的末尾,我想用我的客户端连接到管道。

我的烟斗:

hPipe = CreateNamedPipe(
    lpszPipename,             
    PIPE_ACCESS_OUTBOUND,       // one way access, only send data
    PIPE_TYPE_MESSAGE |       // message type pipe
    PIPE_READMODE_MESSAGE |   // message-read mode
    PIPE_WAIT,                
    PIPE_UNLIMITED_INSTANCES, 
    512,
    512,                  
    0,                        
    NULL);                    

if (hPipe == INVALID_HANDLE_VALUE)

    Out->msg(ERR,"Creating the pipe failed.");


 // Create a thread for this client.
hThread = CreateThread(
    NULL,              // no security attribute
    0,                 // default stack size
    InstanceThread,    // thread proc
    (LPVOID) hPipe,    // thread parameter
    0,                 // not suspended
    &dwThreadId);      // returns thread ID

if (hThread == NULL)

    Out->msg(ERR,"Creating the thread failed.");

else CloseHandle(hThread);

// Close the pipe.
 CloseHandle(hPipe);

我的主题:

DWORD WINAPI InstanceThread(LPVOID lpvParam)

    Out->msg(output::SEV_INFO,"Waiting for client to connect.");
    fConnected = ConnectNamedPipe(hPipe, NULL) ? //This is where the execution hangs
    TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);

    HANDLE hHeap      = GetProcessHeap();
    TCHAR* pchReply   = (TCHAR*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(TCHAR));

    DWORD cbBytesRead = 0, cbReplyBytes = 0, cbWritten = 0;
    BOOL fSuccess = FALSE;
    HANDLE hPipe  = NULL;

// The thread's parameter is a handle to a pipe object instance.

    hPipe = (HANDLE) lpvParam;
    uint32_t startTime = time(NULL);
    uint32_t elapsedTime;
// Loop until done reading
    while ((elapsedTime < 60))
    
        elapsedTime = difftime(time(NULL), startTime);
        // Write to the pipe.
        fSuccess = WriteFile(
            hPipe,        // handle to pipe
            pchReply,     // buffer to write from
            cbReplyBytes, // number of bytes to write
            &cbWritten,   // number of bytes written
            NULL);        // not overlapped I/O

        if (!fSuccess || cbReplyBytes != cbWritten)
        
            Out->msg(ERR,"InstanceThread WriteFile failed.");
            break;
        
    

// 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(hPipe);
    DisconnectNamedPipe(hPipe);
    CloseHandle(hPipe);

    HeapFree(hHeap, 0, pchReply);

    Out->msg(output::SEV_INFO,"InstanceThread exitting.\n");
    return 1;

【问题讨论】:

Named Pipes server, how to interrupt or timeout the wait for client connection and for incoming data的可能重复 【参考方案1】:

我正在尝试让我的命名管道服务器跳过 ConnectNamedPipe 函数的块等待,直到我的客户端尝试连接。

所以你说的是服务器。

所以我希望我的代码继续通过ConnectNamedPipe 行,同时仍然能够连接到我的服务器。

所以你说的是客户。

这没有意义。 ConnectNamedPipe() 是一个服务器端函数,您在专用于它的线程中没有任何有用的事情可做,除非在客户端连接之前阻塞。那就这样做吧。

【讨论】:

对此感到抱歉。我的服务器文件上有 ConnectNamedPipe 代码。它执行并运行,直到遇到包含 ConnectNamedPipe 的线程。然后它等待我的客户端连接。我想要它做的是继续运行我的代码直到结束,然后当它到达结束时,我的客户端将连接到管道。 继续运行到什么结束?在客户端连接之前,它如何对管道做任何事情? 正是哈哈,在客户端连接之前,我还想在代码中先做一些其他的事情,所以我希望代码继续并做这些事情,然后当它完成时我'将执行客户端代码,它将连接到此管道。 所以将 ConnectNamedPipe() 调用移动到您准备阻止的位置。 我很想这样做,但我不能这样做,因为我需要在执行客户端 cpp 文件之前完成整个服务器 cpp 代码。所以如果可能的话,我只需要代码的这个线程部分在后台运行。

以上是关于命名管道在后台等待客户端,直到客户端连接的主要内容,如果未能解决你的问题,请参考以下文章

在断开连接之前等待读取命名管道

网络上的命名管道

当客户端除了快速连接-断开之外啥都不做时,命名管道会失败

命名管道:服务器端如何知道客户端已断开连接?

如何使用重叠 I/O 检测到命名管道服务器的客户端连接?

C#命名管道,如何检测客户端断开连接