0

Everything works fine on one computer.

Server Code:

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

#define PIPE TEXT("\\\\.\\pipe\\Tube")
#define MAX_SIZE_OF_BUFFER 64

string GetErrorMsgText(int code);
string SetPipeError(string msgText, int code);

int main()
{
    try {
        setlocale(LC_ALL, "rus");
        HANDLE sH;


        if ((sH = CreateNamedPipe(
            PIPE, // Имя канала
            PIPE_ACCESS_DUPLEX, // флаги направления канала (PIPE_ACCESS_DUPLEX - разрешает чтение и запись в канал)
            PIPE_TYPE_MESSAGE | PIPE_WAIT, // разрешает запись данных сообщениями\потоком байт в синхронном режиме
            1, // Максимальное кол-во экземпляров канала
            NULL, // размер выходного буфера
            NULL, // размер входного буфера
            INFINITE, // время ожидания связи с клиентом
            NULL)) == INVALID_HANDLE_VALUE) // аттрибуты безопасности 
        {
            throw SetPipeError("CreateNamedPipe:", GetLastError());

        }

        if (!ConnectNamedPipe(sH, NULL)) {
            throw SetPipeError("ConnectNamedPipe:", GetLastError());
        }
        
        cout << "Начинаем прослушку" << endl;

        DWORD dwRead;
        char buffer[50];

        while (ReadFile(sH, buffer, strlen(buffer-1), &dwRead, NULL) != FALSE)
        {
            cout << "Клиент прислал СМС: " << buffer << endl;
            WriteFile(sH, &buffer, strlen(buffer), &dwRead, NULL);
        }
        

        if (!DisconnectNamedPipe(sH)) {
            throw SetPipeError("DisconnectNamedPipe:", GetLastError());
        }
        if (!CloseHandle(sH)) {
            throw SetPipeError("CloseHandle:", GetLastError());
        }
    }
    catch (string ErrorPipeText) {
        cout << endl << ErrorPipeText;
    }
    
}

string GetErrorMsgText(int code) // Функция позволяет получить сообщение ошибки
{
    switch (code)                      // check return code   
    {
    case WSAEINTR: return "WSAEINTR: Работа функции прервана ";
    case WSAEACCES: return "WSAEACCES: Разрешение отвергнуто";
    case WSAEFAULT: return "WSAEFAULT: Ошибочный адрес";
    case WSAEINVAL: return "WSAEINVAL: Ошибка в аргументе";
    case WSAEMFILE: return "WSAEMFILE: Слишком много файлов открыто";
    case WSAEWOULDBLOCK: return "WSAEWOULDBLOCK: Ресурс временно недоступен";
    case WSAEINPROGRESS: return "WSAEINPROGRESS: Операция в процессе развития";
    case WSAEALREADY: return "WSAEALREADY: Операция уже выполняется";
    case WSAENOTSOCK: return "WSAENOTSOCK: Сокет задан неправильно";
    case WSAEDESTADDRREQ: return "WSAEDESTADDRREQ: Требуется адрес расположения";
    case WSAEMSGSIZE: return "WSAEMSGSIZE: Сообщение слишком длинное";
    case WSAEPROTOTYPE: return "WSAEPROTOTYPE: Неправильный тип протокола для сокета";
    case WSAENOPROTOOPT: return "WSAENOPROTOOPT: Ошибка в опции протокола";
    case WSAEPROTONOSUPPORT: return "WSAEPROTONOSUPPORT: Протокол не поддерживается";
    case WSAESOCKTNOSUPPORT: return "WSAESOCKTNOSUPPORT: Тип сокета не поддерживается";
    case WSAEOPNOTSUPP: return "WSAEOPNOTSUPP: Операция не поддерживается";
    case WSAEPFNOSUPPORT: return "WSAEPFNOSUPPORT: Тип протоколов не поддерживается";
    case WSAEAFNOSUPPORT: return "WSAEAFNOSUPPORT: Тип адресов не поддерживается протоколом";
    case WSAEADDRINUSE: return "WSAEADDRINUSE: Адрес уже используется";
    case WSAEADDRNOTAVAIL: return "WSAEADDRNOTAVAIL: Запрошенный адрес не может быть использован";
    case WSAENETDOWN: return "WSAENETDOWN: Сеть отключена";
    case WSAENETUNREACH: return "WSAENETUNREACH: Сеть не достижима";
    case WSAENETRESET: return "WSAENETRESET: Сеть разорвала соединение";
    case WSAECONNABORTED: return "WSAECONNABORTED: Программный отказ связи";
    case WSAECONNRESET: return "WSAECONNRESET: Связь восстановлена";
    case WSAENOBUFS: return "WSAENOBUFS: Не хватает памяти для буферов";
    case WSAEISCONN: return "WSAEISCONN: Сокет уже подключен";
    case WSAENOTCONN: return "WSAENOTCONN: Сокет не подключен";
    case WSAESHUTDOWN: return "WSAESHUTDOWN: Нельзя выполнить send : сокет завершил работу";
    case WSAETIMEDOUT: return "WSAETIMEDOUT: Закончился отведенный интервал  времени";
    case WSAECONNREFUSED: return "WSAECONNREFUSED: Соединение отклонено";
    case WSAEHOSTDOWN: return "WSAEHOSTDOWN: Хост в неработоспособном состоянии";
    case WSAEHOSTUNREACH: return "WSAEHOSTUNREACH: Нет маршрута для хоста";
    case WSAEPROCLIM: return "WSAEPROCLIM: Слишком много процессов";
    case WSASYSNOTREADY: return "WSASYSNOTREADY: Сеть не доступна";
    case WSAVERNOTSUPPORTED: return "WSAVERNOTSUPPORTED: Данная версия недоступна";
    case WSANOTINITIALISED: return "WSANOTINITIALISED: Не выполнена инициализация WS2_32.DLL";
    case WSAEDISCON: return "WSAEDISCON: Выполняется отключение";
    case WSATYPE_NOT_FOUND: return "WSATYPE_NOT_FOUND: Класс не найден";
    case WSAHOST_NOT_FOUND: return "WSAHOST_NOT_FOUND: Хост не найден";
    case WSATRY_AGAIN: return "WSATRY_AGAIN: Неавторизированный хост не найден";
    case WSANO_RECOVERY: return "WSANO_RECOVERY: Неопределенная ошибка";
    case WSANO_DATA: return "WSANO_DATA: Нет записи запрошенного типа";
    case WSA_INVALID_HANDLE: return "WSA_INVALID_HANDLE: Указанный дескриптор события с ошибкой";
    case WSA_INVALID_PARAMETER: return "WSA_INVALID_PARAMETER: Один или более параметров с ошибкой";
    case WSA_IO_INCOMPLETE: return "WSA_IO_INCOMPLETE: Объект ввода - вывода не в сигнальном состоянии";
    case WSA_IO_PENDING: return "WSA_IO_PENDING: Операция завершится позже";
    case WSA_NOT_ENOUGH_MEMORY: return "WSA_NOT_ENOUGH_MEMORY: Не достаточно памяти";
    case WSA_OPERATION_ABORTED: return "WSA_OPERATION_ABORTED: Операция отвергнута";
    case WSASYSCALLFAILURE: return "WSASYSCALLFAILURE: Аварийное завершение системного вызова";
    default: return "**ERROR**";
    };
}

string SetPipeError(string msgText, int code) // Функция возвращает сообщение ошибки
{
    return msgText + GetErrorMsgText(code);
}

Client Code:

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


#define PIPEG TEXT("\\\\servname\\pipe\\Tube")
#define PIPEL TEXT("\\\\.\\pipe\\Tube")
#define MAX_SIZE_OF_BUFFER 64

string GetErrorMsgText(int code);
string SetPipeError(string msgText, int code);
 
int main()
{
    try {
        setlocale(LC_ALL, "rus");
        HANDLE cH;
        if ((cH = CreateFile(PIPEG, // Имя канала
            GENERIC_READ | GENERIC_WRITE, // Чтение и запись
            0, // Совместное чтение и запись
            NULL, // атрибуты безопасности
            OPEN_EXISTING, //  открытие существующего канала
            NULL, // флаги и атрибуты
            NULL)) == INVALID_HANDLE_VALUE) // доп флаги
        {
            throw SetPipeError("CreateFile:", GetLastError());
        }
        
        DWORD dwWrite;
        char buffer[50] = {"Hello Server"};

        int count;
        cout << "Введите кол-во сообщений: ";
        cin >> count;

        for (int i = 1; i <= count; i++) {
            if (!WriteFile(cH, &buffer, strlen(buffer - 1), &dwWrite, NULL)) {
                throw SetPipeError("WriteFile:", GetLastError());
            }

            if (!ReadFile(cH, buffer, MAX_SIZE_OF_BUFFER, &dwWrite, NULL)) {
                throw SetPipeError("ReadFile:", GetLastError());
            }
            cout << "Сервер прислал СМС: " << buffer << endl;
        }
         

        if (!CloseHandle(cH)) {
            throw SetPipeError("CloseHandle:", GetLastError());
        }
    }
    catch (string ErrorPipeText) {
        cout << endl << ErrorPipeText;
    }
    
}

string GetErrorMsgText(int code) // Функция позволяет получить сообщение ошибки
{
    switch (code)                      // check return code   
    {
    case WSAEINTR: return "WSAEINTR: Работа функции прервана ";
    case WSAEACCES: return "WSAEACCES: Разрешение отвергнуто";
    case WSAEFAULT: return "WSAEFAULT: Ошибочный адрес";
    case WSAEINVAL: return "WSAEINVAL: Ошибка в аргументе";
    case WSAEMFILE: return "WSAEMFILE: Слишком много файлов открыто";
    case WSAEWOULDBLOCK: return "WSAEWOULDBLOCK: Ресурс временно недоступен";
    case WSAEINPROGRESS: return "WSAEINPROGRESS: Операция в процессе развития";
    case WSAEALREADY: return "WSAEALREADY: Операция уже выполняется";
    case WSAENOTSOCK: return "WSAENOTSOCK: Сокет задан неправильно";
    case WSAEDESTADDRREQ: return "WSAEDESTADDRREQ: Требуется адрес расположения";
    case WSAEMSGSIZE: return "WSAEMSGSIZE: Сообщение слишком длинное";
    case WSAEPROTOTYPE: return "WSAEPROTOTYPE: Неправильный тип протокола для сокета";
    case WSAENOPROTOOPT: return "WSAENOPROTOOPT: Ошибка в опции протокола";
    case WSAEPROTONOSUPPORT: return "WSAEPROTONOSUPPORT: Протокол не поддерживается";
    case WSAESOCKTNOSUPPORT: return "WSAESOCKTNOSUPPORT: Тип сокета не поддерживается";
    case WSAEOPNOTSUPP: return "WSAEOPNOTSUPP: Операция не поддерживается";
    case WSAEPFNOSUPPORT: return "WSAEPFNOSUPPORT: Тип протоколов не поддерживается";
    case WSAEAFNOSUPPORT: return "WSAEAFNOSUPPORT: Тип адресов не поддерживается протоколом";
    case WSAEADDRINUSE: return "WSAEADDRINUSE: Адрес уже используется";
    case WSAEADDRNOTAVAIL: return "WSAEADDRNOTAVAIL: Запрошенный адрес не может быть использован";
    case WSAENETDOWN: return "WSAENETDOWN: Сеть отключена";
    case WSAENETUNREACH: return "WSAENETUNREACH: Сеть не достижима";
    case WSAENETRESET: return "WSAENETRESET: Сеть разорвала соединение";
    case WSAECONNABORTED: return "WSAECONNABORTED: Программный отказ связи";
    case WSAECONNRESET: return "WSAECONNRESET: Связь восстановлена";
    case WSAENOBUFS: return "WSAENOBUFS: Не хватает памяти для буферов";
    case WSAEISCONN: return "WSAEISCONN: Сокет уже подключен";
    case WSAENOTCONN: return "WSAENOTCONN: Сокет не подключен";
    case WSAESHUTDOWN: return "WSAESHUTDOWN: Нельзя выполнить send : сокет завершил работу";
    case WSAETIMEDOUT: return "WSAETIMEDOUT: Закончился отведенный интервал  времени";
    case WSAECONNREFUSED: return "WSAECONNREFUSED: Соединение отклонено";
    case WSAEHOSTDOWN: return "WSAEHOSTDOWN: Хост в неработоспособном состоянии";
    case WSAEHOSTUNREACH: return "WSAEHOSTUNREACH: Нет маршрута для хоста";
    case WSAEPROCLIM: return "WSAEPROCLIM: Слишком много процессов";
    case WSASYSNOTREADY: return "WSASYSNOTREADY: Сеть не доступна";
    case WSAVERNOTSUPPORTED: return "WSAVERNOTSUPPORTED: Данная версия недоступна";
    case WSANOTINITIALISED: return "WSANOTINITIALISED: Не выполнена инициализация WS2_32.DLL";
    case WSAEDISCON: return "WSAEDISCON: Выполняется отключение";
    case WSATYPE_NOT_FOUND: return "WSATYPE_NOT_FOUND: Класс не найден";
    case WSAHOST_NOT_FOUND: return "WSAHOST_NOT_FOUND: Хост не найден";
    case WSATRY_AGAIN: return "WSATRY_AGAIN: Неавторизированный хост не найден";
    case WSANO_RECOVERY: return "WSANO_RECOVERY: Неопределенная ошибка";
    case WSANO_DATA: return "WSANO_DATA: Нет записи запрошенного типа";
    case WSA_INVALID_HANDLE: return "WSA_INVALID_HANDLE: Указанный дескриптор события с ошибкой";
    case WSA_INVALID_PARAMETER: return "WSA_INVALID_PARAMETER: Один или более параметров с ошибкой";
    case WSA_IO_INCOMPLETE: return "WSA_IO_INCOMPLETE: Объект ввода - вывода не в сигнальном состоянии";
    case WSA_IO_PENDING: return "WSA_IO_PENDING: Операция завершится позже";
    case WSA_NOT_ENOUGH_MEMORY: return "WSA_NOT_ENOUGH_MEMORY: Не достаточно памяти";
    case WSA_OPERATION_ABORTED: return "WSA_OPERATION_ABORTED: Операция отвергнута";
    case WSASYSCALLFAILURE: return "WSASYSCALLFAILURE: Аварийное завершение системного вызова";
    case ERROR_LOGON_FAILURE: return "ERROR_LOGON_FAILURE: 1326: Вход в систему не произведен: имя пользователя или пароль не опознаны.";
    case ERROR_FILE_NOT_FOUND: return "ERROR_FILE_NOT_FOUND: Не удалось найти файл(канал)";
    case ERROR_ACCESS_DENIED: return "ERROR_ACCESS_DENIED: Отказано в доступе";
    default: return "**ERROR**";
    };
}

string SetPipeError(string msgText, int code) // Функция возвращает сообщение ошибки
{
    return msgText + GetErrorMsgText(code);
}

Naturally, when trying to establish a connection on different computers on the local network, in the client application, I changed the servname in #define PIPEG TEXT("\\\\servname\\pipe\\Tube") to the hostname of the server computer.

But there is always an error:

ERROR_ACCESS_DENIED: Access denied

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Artyom
  • 1
  • https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipe-security-and-access-rights – Hans Passant Mar 09 '23 at 21:58
  • @HansPassant I read it. And what should I do to correct this error? – Artyom Mar 09 '23 at 22:07
  • you need first call `WNetAddConnection2W` with `lpRemoteName = L"\\\\servname\\IPC$";` and `dwUsage = RESOURCEUSAGE_CONNECTABLE|RESOURCEUSAGE_CONTAINER;` – RbMm Mar 09 '23 at 22:14
  • @RbMm can you write what exactly it should look like in the code, if it's not difficult for you? – Artyom Mar 09 '23 at 22:16
  • https://stackoverflow.com/a/52804146/6401656 – RbMm Mar 09 '23 at 22:22
  • Named pipes are securable objects. Unless you actually want to configure security on them, you can alternatively just give `CreateNamedPipe()` a valid `SECURITY_ATTRIBUTES` whose `SECURITY_DESCRIPTOR` has a NULL DACL assigned to it, then the pipe will be able to accept any client. No need to use `WNetAddConnection2()`, I've been doing it this way for years, it has always worked fine for me. – Remy Lebeau Mar 09 '23 at 22:27
  • @RemyLebeau can u show me how i can make it for my code, please? – Artyom Mar 09 '23 at 22:33
  • @Artyom see [this answer](https://stackoverflow.com/a/14502613/65863) – Remy Lebeau Mar 09 '23 at 22:43

0 Answers0