Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
1 / 1 / 1
Регистрация: 27.02.2010
Сообщений: 71
1

Передача данных между консолью с использованием Pipe

25.07.2019, 22:40. Показов 1264. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день!

Не получается организовать передачу данных между двумя консольными приложениями при использовании буфера с типом wchar_t. Если использую просто char все нормально работает.
С клиента отправка вроде как происходит без ошибок и сервер даже получает сообщение, затем отправляет ответ клиенту. Клиент получает сообщение, но дальше при отправке последующих сообщений сервер никак не реагирует. Когда отправляю пустые строки тоже все нормально отрабатывает

Где я мог ошибиться, может подскажет кто нибудь?

Сервер
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
int main(){
 
    BOOL   fConnected;
    HANDLE hNamedPipe;
    LPCWSTR   lpszPipeName = L"\\\\.\\pipe\\$MyPipe$";
    wchar_t   szBuf[1024];
    DWORD  cbRead;
    DWORD  cbWritten;
 
    hNamedPipe = CreateNamedPipe(
        lpszPipeName,
        PIPE_ACCESS_DUPLEX,
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
        PIPE_UNLIMITED_INSTANCES,
        1024, 1024, 5000, NULL);
 
    if (hNamedPipe == INVALID_HANDLE_VALUE)
    {
        fprintf(stdout, "CreateNamedPipe: Error %ld\n",
            GetLastError());
        _getch();
        return 0;
    }
 
 
    fprintf(stdout, "Waiting for connect...\n");
 
    fConnected = ConnectNamedPipe(hNamedPipe, NULL);
 
    if (CheckConnect(fConnected, hNamedPipe) == 0)
        return 0;
    
    fprintf(stdout, "\nConnected. Waiting for command...\n");
 
    // Цикл получения команд через канал
    while (1)
    {
        // Получаем очередную команду через канал Pipe
        if (ReadFile(hNamedPipe, &szBuf, 1024, &cbRead, NULL))
        {
            // Посылаем эту команду обратно клиентскому
            // приложению
            if (!WriteFile(hNamedPipe, szBuf, wcslen(szBuf) + 1, &cbWritten, NULL))
                break;
 
            // Выводим принятую команду на консоль 
            wprintf(L"Received: <%s>\n", szBuf);
 
            // Если пришла команда "exit", 
            // завершаем работу приложения
            if (!wcscmp(szBuf, L"exit"))
                break;
        }
        else
        {
            fprintf(stdout, "ReadFile: Error %ld\n", GetLastError());
 
            hNamedPipe = CreateNamedPipe(
                lpszPipeName,
                PIPE_ACCESS_DUPLEX,
                PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
                PIPE_UNLIMITED_INSTANCES,
                512, 512, 5000, NULL);
            if (hNamedPipe == INVALID_HANDLE_VALUE)
            {
                fprintf(stdout, "CreateNamedPipe: Error %ld\n",
                    GetLastError());
                _getch();
                return 0;
            }
            fConnected = ConnectNamedPipe(hNamedPipe, NULL);
            if (CheckConnect(fConnected, hNamedPipe) == 0)
                return 0;
            //break;
        }
    }
 
    CloseHandle(hNamedPipe);
    return 0;
}
Клиент
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include  <fstream>
#include <iostream>
 
int main(int argc, char* argv[]){
 
    HANDLE hNamedPipe;
    DWORD  cbWritten;
    DWORD  cbRead;
    wchar_t   szBuf[512];
 
    LPCWSTR   szPipeName = L"\\\\.\\pipe\\$MyPipe$";
 
    hNamedPipe = CreateFile(szPipeName, GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, 0, NULL);
 
    if (hNamedPipe == INVALID_HANDLE_VALUE)
    {
        fprintf_s(stdout, "CreateFile: Error %ld\n",
            GetLastError());
        _getch();
        return 0;
    }
 
    fprintf(stdout, "\nConnected. Type 'exit' to terminate\n");
 
    // Цикл обмена данными с серверным процессом
    while (1)
    {
        // Выводим приглашение для ввода команды
        printf("cmd>");
 
        // Вводим текстовую строку
        _getws_s(szBuf);
 
        // Передаем введенную строку серверному процессу
        // в качестве команды
        if (!WriteFile(hNamedPipe, szBuf, wcslen(szBuf) + 1,&cbWritten, NULL))
            break;
 
        // Получаем эту же команду обратно от сервера
        if (ReadFile(hNamedPipe, szBuf, 1024, &cbRead, NULL))
            //std::wcout << szBuf << std::endl;
            wprintf_s(L"Received back: <%s>\n", szBuf);
 
        // Если произошла ошибка, выводим ее код и
        // завершаем работу приложения
        else
        {
            fprintf(stdout, "ReadFile: Error %ld\n",
                GetLastError());
            _getch();
            break;
        }
 
        // В ответ на команду "exit" завершаем цикл
        // обмена данными с серверным процессом
        if (!wcscmp(szBuf, L"exit"))
            break;
    }
 
    // Закрываем идентификатор канала
    CloseHandle(hNamedPipe);
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.07.2019, 22:40
Ответы с готовыми решениями:

Передача данных между процессами (pipe)
Всем доброго времени суток. Обращаюсь к вам с вопросиком. Передо мной стоит задача написать код,...

Передача данных дочернему процессу посредством pipe(): иммитация нажатия enter через терминал
Всем привет. Столкнулся с такой проблемой: есть программа, считывающая логин и пароль...

Передача ссылки в конструктор (передача данных между формами)
Из темы &quot;Ответы на 7 самых частых вопроса по WinForms&quot; Реализовал метод № 2.3 без проблем, а вот...

Передача аргументов между потоками с использованием делегатов
Правильно ли я понимаю что делегат будет вызван в том потоке в котором я его создал, а не в том в...

2
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
25.07.2019, 23:24 2
Цитата Сообщение от Teem Посмотреть сообщение
wcslen(szBuf) + 1
(wcslen(szBuf) + 1) * sizeof(wchar_t)

После вызова CreateFile тебе нужно вручную установить флаг PIPE_READMODE_MESSAGE для пайпа (функцией SetNamedPipeHandleState). По-умолчанию выставляется PIPE_READMODE_BYTE.
1
1 / 1 / 1
Регистрация: 27.02.2010
Сообщений: 71
27.07.2019, 14:03  [ТС] 3
Спасибо. Помогло)))
0
27.07.2019, 14:03
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.07.2019, 14:03
Помогаю со студенческими работами здесь

Передача данных по Анонимным (Неименованым) каналам с последующим использованием этих данных
Всем доброго времени суток. Нужна помощь: Имеется Сервер и Клиент связанные анонимным каналом....

Передача строки символов между процессами с использованием именованных каналов
Нашел пример по теме, но как нужно запускать эти части и произвести передачу данных от одного...

Передача сообщений через pipe
Прошу помочь с реализацией курсового проекта. Я очень плохо шарю в c++, поэтому ничего не могу...

Передача данных с использованием SocketChannel
При регистрации селектором нового соединения создаем SocketChannel, устанавливаем его в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru