连接到命名管道

时间:2020-04-30 13:31:31

标签: c++ winapi network-programming

我尝试在C ++中使用命名管道将消息从一台计算机传输到另一台计算机。但是客户端无法连接到服务器,尽管正确指定了服务器名称,但它返回错误1326(无效的名称或密码)。

密码与频道有什么关系?如果代码中没有错误,那么还有什么原因会导致与通道的连接错误?

此外,在Internet上,我看到了这样一个记录频道名称\\servername\pipe\[path] pipename的表格。 servername是服务器的名称,pipe确定它是一个通道,而pipename是该通道的名称,但是[path]是什么?

服务器

#include <windows.h>
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    HANDLE hNamedPipe;
    DWORD dwBytesRead; 
    DWORD dwBytesWrite; 
    char pchMessage[80];
    int nMessageLength;

    PSECURITY_DESCRIPTOR psd;
    SECURITY_ATTRIBUTES sa;
    psd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
    InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(psd, true, NULL, false);
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = true;
    sa.lpSecurityDescriptor = psd;

    hNamedPipe= CreateNamedPipe("\\\\.\\pipe\\pipe", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_OWNER, PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE| PIPE_ACCEPT_REMOTE_CLIENTS, PIPE_UNLIMITED_INSTANCES, 2048, 2048, INFINITE, &sa);
    if (hNamedPipe == INVALID_HANDLE_VALUE)
    {
            cerr << "Create named pipe failed." << endl
            << "The last error code: " << GetLastError() << endl;
        cout << "Press any key to exit.";
        cin.get();

        return 0;
    }
    cout << "The server is waiting for connection with a client." << endl;
    if (!ConnectNamedPipe(
        hNamedPipe,
        NULL 
    ))
    {
        cerr << "Connect named pipe failed." << endl
            << "The last error code: " << GetLastError() << endl;
        CloseHandle(hNamedPipe);
        cout << "Press any key to exit.";
        cin.get();

        return 0;
    }
    if (!ReadFile(
        hNamedPipe,
        pchMessage,
        sizeof(pchMessage),
        &dwBytesRead, 
        NULL))
    {
        cerr << "Data reading from the named pipe failed." << endl
            << "The last error code: " << GetLastError() << endl;
        CloseHandle(hNamedPipe);
        cout << "Press any key to exit.";
        cin.get();

        return 0;
    }

    cout << "The server received the message from a client: "
        << endl << '\t' << pchMessage << endl;

    cout << "Input a string: ";
    cin.getline(pchMessage, 80);
    nMessageLength = strlen(pchMessage) + 1;

        if (!WriteFile(
            hNamedPipe,
            pchMessage,
            nMessageLength,
            &dwBytesWrite,
            NULL
        ))
        {
            cerr << "Write file failed." << endl
                << "The last error code: " << GetLastError() << endl;
            CloseHandle(hNamedPipe);
            cout << "Press any key to exit.";
            cin.get();

            return 0;
        }

    cout << "The server sent the message to a client: "
        << endl << '\t' << pchMessage << endl;

    CloseHandle(hNamedPipe);
    cout << "Press any key to exit.";
    cin.get();

    return 0;
}

客户

#include <windows.h>
#include <iostream>
#include <string>
using namespace std;

int main()
{
    string machineName;
    getline(cin, machineName, '\n');
    machineName= "\\\\"+machineName+"\\pipe\\pipe";
    cout << machineName << endl;
    char pipeName[80];
    strcpy_s(pipeName, machineName.c_str());
    HANDLE hNamedPipe;
    DWORD dwBytesWritten;
    DWORD dwBytesRead;
    char pchMessage[80];
    int nMessageLength;

    hNamedPipe = CreateFile(
        pipeName, // имя канала
        GENERIC_READ | GENERIC_WRITE, 
        FILE_SHARE_READ | FILE_SHARE_WRITE, 
        NULL, 
        OPEN_EXISTING, 
        FILE_ATTRIBUTE_NORMAL, 
        NULL);

    if (hNamedPipe == INVALID_HANDLE_VALUE)
    {
        cerr << "Connection with the named pipe failed." << endl
            << "The last error code: " << GetLastError() << endl;
        cout << "Press any key to exit.";
        cin.get();
        return 0;
    }
    cin.get();
    cout << "Input a string: ";
    cin.getline(pchMessage, 80);
    nMessageLength = strlen(pchMessage) + 1;
    if (!WriteFile(
        hNamedPipe, 
        pchMessage, 
        nMessageLength,
        &dwBytesWritten,
        NULL)) 
    {
            cerr << "Write file failed: " << endl
            << "The last error code: " << GetLastError() << endl;
        CloseHandle(hNamedPipe);
        cout << "Press any key to exit.";
        cin.get();
        return 0;
    }
        cout << "The client sent the message to a server: "
        << endl << '\t' << pchMessage << endl;
    if (!ReadFile(
        hNamedPipe, 
        pchMessage,
        sizeof(pchMessage), 
        &dwBytesRead,
        NULL))
    {
        cerr << "Read file failed: " << endl
            << "The last error code: " << GetLastError() << endl;
        CloseHandle(hNamedPipe);
        cout << "Press any key to exit.";
        cin.get();
        return 0;
    }
    cout << "The client received the message from a server: "
        << endl << '\t' << pchMessage << endl;
    CloseHandle(hNamedPipe);
    cout << "Press any key to exit.";
    cin.get();
    return 0;
}

1 个答案:

答案 0 :(得分:0)

经过我的测试,您的代码中有两个地方需要更正。

NetUseAdd函数在本地之间建立连接 计算机和远程服务器。您可以指定本地驱动器号或 要连接的打印机设备。如果不指定本地驱动器 信件或打印机设备,该功能通过 服务器以供将来连接。

此外,file and print sharing需要打开。

引用:SMB named pipe with no connection restrictions

配置完所有内容后,代码即可正常工作。

相关问题