简体   繁体   English

命名管道问题

[英]Named Pipes Issue

I am trying to learn how named pipes work, and created 2 consoles to test the connectivity between server and client. 我正在尝试学习命名管道的工作原理,并创建了2个控制台来测试服务器和客户端之间的连接。 Client will send a message to the server and the server will display the message, but instead of the message, it returns a value of "nullptr" as shown in the error exception break from VS. 客户端将向服务器发送一条消息,服务器将显示该消息,但代替该消息,它会返回值“ nullptr”,如VS的错误异常中断所示。

below are my codes, do enlighten me if you found any problem with my code, and I am still learning.. 以下是我的代码,如果您发现我的代码有任何问题,请告诉我,我仍在学习。

Server.cpp Server.cpp

#include "cust_ostream.hpp"
#include <Windows.h>
#include <iostream>
#include <conio.h>

using namespace std;

int main()
{
    LPVOID buffer = NULL;
    DWORD readbyte;

    cout << "---Named Pipe Server Test---" << endl << endl;
    cout << "Creating named pipe: \\\\.\\pipe\\mypipe" << endl;

    HANDLE hPipe = CreateNamedPipeA("\\\\.\\pipe\\mypipe", PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
        PIPE_UNLIMITED_INSTANCES, 1024, 1024, 0, NULL);

    if (!hPipe || hPipe == INVALID_HANDLE_VALUE)
    {
        cout << "Pipe creation failed." << endl;
        return 0;
    }

    cout << "Connecting pipe to client..." << endl;

    BOOL connect = ConnectNamedPipe(hPipe, NULL);

    if (!connect)
    {
        cout << "Connect named pipe failed" << endl;
    }

    cout << "Success! Reading pipe message from client..." << endl;

    ReadFile(hPipe, buffer, sizeof(buffer), &readbyte, NULL);

    c_cout << "Pipe message = " << *(int *)buffer << endl;

    _getch();

    return 0;
}

cust_ostream.hpp cust_ostream.hpp

#include <Windows.h>
#include <iostream>
#include <sstream>

using namespace std;

#define endl "\n"

class cust_ostream
{
public:
    ~cust_ostream()
    {
        cout << m_buffer.str();
    }

    template <typename T>
    cust_ostream &operator<<(T const &value)
    {
        m_buffer << value;
        return *this;
    }

private:
    ostringstream m_buffer;
};

#define c_cout cust_ostream()

and my client 和我的客户

#include <Windows.h>
#include <iostream>
#include <conio.h>

using namespace std;

int main()
{
    LPVOID data;
    DWORD writebyte;

    int i = 2;

    cout << "---Named Pipe Client---" << endl << endl;
    cout << "Creating pipe file: \\\\.\\pipe\\mypipe" << endl;

    HANDLE pipe = CreateFileA("\\\\.\\pipe\\mypipe", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

    if (!pipe || pipe == INVALID_HANDLE_VALUE)
    {
        cout << "Pipe client failed." << endl;
        return 0;
    }

    cout << "Pipe connected to server, sending data..." << endl;

    WriteFile(pipe, &i, sizeof(i), &writebyte, NULL);

    _getch();

    return 0;
}

You need to wait for the NamedPipe to have a ConnectPipeReady event on it. 您需要等待NamedPipe上具有ConnectPipeReady事件。 As it stands, you are trying to create the pipe without actually seeing if it was succesfull. 就目前而言,您正在尝试创建管道,而没有实际查看管道是否成功。 See the MSDN documentation for Named Pipes here: https://msdn.microsoft.com/en-ca/library/windows/desktop/aa365592(v=vs.85).aspx 请参阅以下有关命名管道的MSDN文档: https : //msdn.microsoft.com/zh-cn/library/windows/desktop/aa365592(v= vs.85).aspx

Specifically, this block: 具体来说,此块:

while (1) 
{ 
  hPipe = CreateFile( 
     lpszPipename,   // pipe name 
     GENERIC_READ |  // read and write access 
     GENERIC_WRITE, 
     0,              // no sharing 
     NULL,           // default security attributes
     OPEN_EXISTING,  // opens existing pipe 
     0,              // default attributes 
     NULL);          // no template file 

  // Break if the pipe handle is valid. 

  if (hPipe != INVALID_HANDLE_VALUE) 
     break; 

  // Exit if an error other than ERROR_PIPE_BUSY occurs. 

  if (GetLastError() != ERROR_PIPE_BUSY) 
  {
     _tprintf( TEXT("Could not open pipe. GLE=%d\n"), GetLastError() ); 
     return -1;
  }

  // All pipe instances are busy, so wait for 20 seconds. 

  if ( ! WaitNamedPipe(lpszPipename, 20000)) 
  { 
     printf("Could not open pipe: 20 second wait timed out."); 
     return -1;
  } 
}

Also you shouldn't use #define endl "\\n" , use std::endl 另外,您不应该使用#define endl "\\n" ,请使用std::endl

You have initialized your buffer as NULL which means that by default its length is zero. 您已将缓冲区初始化为NULL,这意味着默认情况下其长度为零。 Now when you use the sizeof operator in your read function in server (to retrieve the message received by server from client), what happens is that you are asking the sizeof operator in Read function to read 0 bytes! 现在,当您在服务器的读取函数中使用sizeof运算符(以检索服务器从客户端接收到的消息)时,发生的事情是您要在Read函数中的sizeof运算符读取0个字节! which means that nothing will be read. 这意味着什么也不会读。

To solve this, you can declare a char array of size 100 or a size of a message which you are sure that won't be exceeded by client. 为了解决这个问题,您可以声明一个大小为100的char数组或一条消息的大小,您确定不会被客户端超过。 Like if you are assuming that message by client is not going to be longer than lets say 60 characters, then you can create your char buffer to be of size 100 just to make sure that you do accommodate all the message by client. 就像假设您假设客户端发送的消息不会超过60个字符那样,那么您可以将char缓冲区的大小设置为100,以确保您确实容纳了客户端发送的所有消息。

And one more thing, if problem still persists, instead of using sizeof in read, use 100 or whatever the size of of your char buffer array. 还有一件事,如果问题仍然存在,请使用100或任何char缓冲区数组的大小,而不是在读取中使用sizeof。 This should solve your problem. 这应该可以解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM