Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.59/22: Рейтинг темы: голосов - 22, средняя оценка - 4.59
0 / 0 / 0
Регистрация: 25.11.2012
Сообщений: 30

Передача данных по Анонимным (Неименованым) каналам с последующим использованием этих данных

14.05.2013, 21:14. Показов 5185. Ответов 36
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброго времени суток. Нужна помощь:
Имеется Сервер и Клиент связанные анонимным каналом. Через анонимный канал нужно передать 4 значения, которые в дальнейшем на сервере протабулируются. Вот пытался это организовать не получилось. Помогите разобраться. Заранее спасибо.
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
//клиент
#include <iostream>
#include <windows.h>
 
using namespace std;
 
int main()
{
    int szBuf[4];
    srand(GetCurrentProcessId());
 
    //"открываем" событие, созданное сервером
    HANDLE hEv = CreateEventA(0, TRUE, FALSE, "READEVENT");
 
    szBuf[0]=(rand()%5)+1;
    szBuf[1]=(szBuf[0]+rand()%20)*2;
    szBuf[2]=rand()%5;
    szBuf[3]=rand()%5;
 
    //пишем в канал (дескриптор вывода переопределен в коде создание процесса в сервере
    std::cout<<"Hi, i'm client\0"<<endl;
    for (int i=0;i<4;i++)
        std::cout<<szBuf[i]<<endl;
    //информируем сервер о готовности данных для чтения
    SetEvent(hEv);
 
    CloseHandle(hEv);
 
    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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//сервер
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <fstream>
#include <cmath>
using namespace std;
 
void tab(int start, int end, int step, int funcnum)
{
    ofstream file("ResultFile.txt",ios_base::app);
    if(start>end)
        swap(start,end);
    if(step==0)
        step++;
    switch(funcnum)
    {
    case 0:
        file<<"Крок: "<<step<<", Початкове значення: "<<start<<", Kiнцеве значення: "<<end<<" функція sin(x) має значення:\n";
        for(int i=start;i<end;i+=step)
        {
            file<<sin(i)<<"\t";
        }
        file<<"\n\n";
        break;
    case 1:
        file<<"Крок: "<<step<<", Початкове значення: "<<start<<", Kiнцеве значення: "<<end<<" функція cos(x) має значення:\n";
        for(int i=start;i<end;i+=step)
        {
            file<<cos(i)<<"\t";
        }
        file<<"\n\n";
        break;
    case 2:
        file<<"Крок: "<<step<<", Початкове значення: "<<start<<", Kiнцеве значення: "<<end<<" функція tg(x) має значення:\n";
        for(int i=start;i<end;i+=step)
        {
            file<<tan(i)<<"\t";
        }
        file<<"\n\n";
        break;
    case 3:
        file<<"Крок: "<<step<<", Початкове значення: "<<start<<", Kiнцеве значення: "<<end<<" функція ctg(x) має значення:\n";
        for(int i=start;i<end;i+=step)
        {
            file<<1/tan(i)<<"\t";
        }
        file<<"\n\n";
        break;
    default:
        file<<"Крок: "<<step<<", Початкове значення: "<<start<<", Kiнцеве значення: "<<end<<" функція 1/x має значення:\n";
        for(int i=start;i<end;i+=step)
        {
            file<<1.0/i<<"\t";
        }
        file<<"\n\n";
    }
    file.close();
}
 
int main()
{
    HANDLE hRead = INVALID_HANDLE_VALUE;
    HANDLE hWrite = INVALID_HANDLE_VALUE;
 
    int szBuf[4];
 
    SECURITY_ATTRIBUTES sa = {sizeof(sa)};
    sa.bInheritHandle = TRUE; //хэндлы наследуемые
    sa.lpSecurityDescriptor = NULL;
 
    //создаем анонимный канал
    if(!CreatePipe(&hRead, &hWrite, &sa, 0))
    {
        std::cout<<"Error code: "<<GetLastError()<<std::endl;
        return -1;
    }
 
    //событие для информирования о доступности чтения
    HANDLE hEv = CreateEventA(0, TRUE, FALSE, "READEVENT");
 
    STARTUPINFOA si = {sizeof(si)};
 
    //передаем хэндлы в процесс-клиент
    si.hStdOutput = hWrite;
    si.hStdInput = hRead;
    si.hStdError = hWrite;
 
    //говорим о необходимости переопределения стандартных дескрипторов
    si.dwFlags = STARTF_USESTDHANDLES;
 
    PROCESS_INFORMATION pi = {0};
 
    //запускаем процесс-клиент
    if(!CreateProcessA(NULL, "CLIENT.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi ))
    {
        std::cout<<"Error code: "<<GetLastError()<<std::endl;
        CloseHandle(hRead);
        CloseHandle(hWrite);
        CloseHandle(hEv);
        return -1;
    }
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
 
    //ждем пока клиент запишет данные
    WaitForSingleObject(hEv, INFINITE);
 
    DWORD readed = 0;
    BYTE buf[255] = {0};
 
    //читаем данные из канала и выводим их (в данном случае будет строка)
    if(ReadFile(hRead, buf, 255, &readed, NULL))
    {
        std::cout<<"Read from pipe:"<< (char*)buf<<std::endl;system("PAUSE");
    }
 
    for (int i=0;i<4;i++)
        std::cout<<szBuf<<endl;
 
    tab(szBuf[0],szBuf[1],szBuf[2],szBuf[3]);
 
    CloseHandle(hRead);
    CloseHandle(hWrite);
    CloseHandle(hEv);
 
    return 0;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.05.2013, 21:14
Ответы с готовыми решениями:

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

запуск и передача данных сторонней программе с последующим возвратом результата в PHP
exec() запускает и возвращает результат, а как еще и передать данные в саму программу?

Вывод всех записей из БД и передача этих данных JS-скрипту
ПОМОГИТЕ ПОЖАЛУЙСТА! есть вот такой вывод php &lt;?php $sql = 'SELECT * FROM statist WHERE user_id = '.$us_id.' order by id DESC'; ...

36
0 / 0 / 0
Регистрация: 25.11.2012
Сообщений: 30
16.05.2013, 16:51  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Убежденный Посмотреть сообщение
1) Что-то я не вижу, где здесь захватывается мьютекс.
2) В данном коде мьютекс не нужен. Нечего охранять.
Упс, в сервер
C++
1
WaitForSingleObject(hMutex, INFINITE);
добавил, а в клиент по всей видимости нет.
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
//---------------------
//    C L I E N T
//---------------------
 
#include <iostream>
#include <Windows.h>
 
int main()
{
    using namespace std;
    srand(GetCurrentProcessId());
 
    HANDLE hMutex;
    hMutex = OpenMutex(SYNCHRONIZE, FALSE, L"DemoMutex");
 
    HANDLE const hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    
    //Захватываем мютекс
    WaitForSingleObject(hMutex, INFINITE); 
    
    // Записываем в устройство переменную типа int.
    int szBuf[4]={0,0,0,0};
    szBuf[0]=(rand()%5)+1;
    szBuf[1]=(szBuf[0]+rand()%20)*2;
    szBuf[2]=rand()%5;
    szBuf[3]=rand()%5;
 
    DWORD nBytes;
    WriteFile(hStdOutput, &szBuf, sizeof (szBuf), &nBytes, NULL);
 
    return EXIT_SUCCESS;
 
    ReleaseMutex(hMutex);
    CloseHandle(hMutex);
}
0
0 / 0 / 0
Регистрация: 25.11.2012
Сообщений: 30
21.05.2013, 19:23  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
Пример использования пайпа для перенаправления стандартного вывода.
Обработка ошибок опущена для наглядности.

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
81
82
83
84
85
86
87
88
89
90
91
//---------------------
//
//    S E R V E R
//
//---------------------
 
 
 
#include <iostream>
#include <Windows.h>
 
 
 
int main()
{
    using namespace std;
 
    // Создаем пайп.
    // Хэндлы пайпа должны быть наследуемыми.
    // Точнее говоря, в данном примере лишь один хэндл должен
    // быть наследуемым, но это сейчас несущественно.
 
    SECURITY_ATTRIBUTES sa;
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;
    sa.nLength = sizeof (sa);    
 
    HANDLE hReadPipe;
    HANDLE hWritePipe;    
 
    CreatePipe(&hReadPipe, &hWritePipe, &sa, 0);
 
    // Заполняем структуру STARTUPINFO для будущего процесса.
    // Подменяем хэндл стандартного вывода на хэндл записи в пайп.
 
    STARTUPINFOW si;
    GetStartupInfoW(&si);
 
    si.dwFlags |= STARTF_USESTDHANDLES;
    si.hStdOutput = hWritePipe;
 
    // Запускаем дочерний процесс.
 
    PROCESS_INFORMATION pi;
 
    wchar_t pCmdLine[] = {L"client.exe"}; // Буфер должен быть изменяемым !
 
    CreateProcessW(NULL,
        pCmdLine,
        NULL,
        NULL,
        TRUE, // <--- Наследовать хэндлы ? Да.
        NORMAL_PRIORITY_CLASS,
        NULL,
        NULL,
        &si,
        &pi);
 
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
 
    // Закрываем хэндл записи - нам он не нужен, а у
    // дочернего процесса уже есть его копия.
 
    CloseHandle(hWritePipe);
 
    // Выделяем буфер достаточного размера, чтобы принять все данные.
 
    DWORD const BuffSize = 100;
    byte *pBuffer = new byte[BuffSize];
 
    // Читаем из пайпа, пока на том конце не завершат запись или
    // пока буфер не будет заполнен.
 
    DWORD nBytes;
 
    ReadFile(hReadPipe, pBuffer, BuffSize, &nBytes, NULL);
    CloseHandle(hReadPipe);
 
    // Получаем int-переменную из буфера и выводим ее на экран.
 
    int const Value = *((int const *)pBuffer);
 
    cout << "Value = " << Value << endl;
 
    // Очистка ресурсов и выход.
 
    delete [] pBuffer;
 
    return EXIT_SUCCESS;
}


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
//---------------------
//
//    C L I E N T
//
//---------------------
 
 
 
#include <iostream>
#include <Windows.h>
 
 
 
int main()
{
    using namespace std;
 
    // Получаем хэндл стандартного вывода.
    // Обычно здесь хэндл консоли, но сейчас серверный
    // процесс подменил его на хэндл пайпа.
    //
    // Альтернатива:
    //
    // STARTUPINFO si;
    // GetStartupInfoW(&si);
    // HANDLE const hStdOutput = si.hStdOutput;
 
    HANDLE const hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 
    // Записываем в устройство переменную типа int.
 
    int const Value = 123;
 
    DWORD nBytes;
    WriteFile(hStdOutput, &Value, sizeof (Value), &nBytes, NULL);
 
    return EXIT_SUCCESS;
}


Вывод:
Почему когда запустить просто клиента на екране появляются непонятные символы? Как сделать так что бы к примеру запустить первым клиента, он каким-то образом подождал запуск сервера и тогда данные уже передались? Если можна на этом примере.

Добавлено через 10 минут
Нужно это вот для чего: к примеру есть 10 запущенных клиентов и 1 запущенный сервер. Нужно сделать так, что бы все они 10 по очереди передали передали данные именно на тот 1 запущенный сервер, а не 10 запусков сервера с вызовом по 1 клиенту. Возможно ли такое?

Добавлено через 24 минуты
Как бы это лучше об"яснить. Процесс-клиент передает данные по анонимному каналу. Процесс-сервер получает из буфера необходимые для работы данные. По завершению переходит к ожиданию новых данных.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
21.05.2013, 22:57
Цитата Сообщение от Yoshi21 Посмотреть сообщение
Почему когда запустить просто клиента на екране появляются непонятные символы?
Потому что клиент пишет в стандартный вывод поток байт напрямую (WriteFile with 123).

Цитата Сообщение от Yoshi21 Посмотреть сообщение
Как сделать так что бы к примеру запустить первым клиента, он каким-то образом подождал запуск сервера и тогда данные уже передались?
Например, вместо перенаправления стандартного вывода использовать именованный канал (named pipe).
Схема: клиент при запуске создает пайп и событие, затем ждет на событии.
Сервер при запуске подключается к пайпу и сигнализирует событием, что, мол, "я готов".
Клиент пишет в пайп данные.

Цитата Сообщение от Yoshi21 Посмотреть сообщение
Нужно это вот для чего: к примеру есть 10 запущенных клиентов и 1 запущенный сервер. Нужно сделать так, что бы все они 10 по очереди передали передали данные именно на тот 1 запущенный сервер, а не 10 запусков сервера с вызовом по 1 клиенту. Возможно ли такое?
Конечно.
Сервер создает пайп (или сокет, или что-нибудь еще из IPC...) и ждет подключений.
Клиенты коннектятся по одному и передают свои данные серверу.
Чтобы они не мешали друг другу, использовать объект синхронизации процессов,
например мьютекс, семафор или событие.
1
0 / 0 / 0
Регистрация: 25.11.2012
Сообщений: 30
23.05.2013, 11:25  [ТС]
Проблема в том, что (я пишу курсовую и обязательным условием задания есть Анонимные каналы и Мьютекс)

Помогите пожалуйста изменить программы сервера и клиент, что бы
Цитата Сообщение от Убежденный Посмотреть сообщение
Сервер ждал подключений. Клиенты коннектятся по одному и передают свои данные серверу.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//---------------------
//    C L I E N T
//--------------------- 
#include <iostream>
#include <Windows.h>
  
int main()
{
    using namespace std;
 
    HANDLE const hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 
    int const Value = 123;
 
    DWORD nBytes;
    WriteFile(hStdOutput, &Value, sizeof (Value), &nBytes, NULL);
 
    return EXIT_SUCCESS;
}
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
//---------------------
//    S E R V E R
//---------------------  
#include <iostream>
#include <Windows.h>
  
int main()
{
    using namespace std;
 
    SECURITY_ATTRIBUTES sa;
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;
    sa.nLength = sizeof (sa);    
 
    HANDLE hReadPipe;
    HANDLE hWritePipe;    
 
    CreatePipe(&hReadPipe, &hWritePipe, &sa, 0);
 
    STARTUPINFOW si;
    GetStartupInfoW(&si);
 
    si.dwFlags |= STARTF_USESTDHANDLES;
    si.hStdOutput = hWritePipe;
 
    PROCESS_INFORMATION pi;
 
    wchar_t pCmdLine[] = {L"client.exe"}; // Буфер должен быть изменяемым !
 
    CreateProcessW(NULL,
        pCmdLine,
        NULL,
        NULL,
        TRUE, // <--- Наследовать хэндлы ? Да.
        NORMAL_PRIORITY_CLASS,
        NULL,
        NULL,
        &si,
        &pi);
 
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
  
    CloseHandle(hWritePipe);
 
    DWORD const BuffSize = 100;
    byte *pBuffer = new byte[BuffSize];
 
    DWORD nBytes;
 
    ReadFile(hReadPipe, pBuffer, BuffSize, &nBytes, NULL);
    CloseHandle(hReadPipe);
 
    int const Value = *((int const *)pBuffer);
 
    cout << "Value = " << Value << endl;
 
    delete [] pBuffer;
 
    return EXIT_SUCCESS;
}
Добавлено через 18 часов 7 минут
Как сделать на этих примерах чтобы не сервер запускали клиента, а они запускались отдельно. Если можна на том примере буквально пару строчек, спасибо.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
23.05.2013, 11:46
Хочу уточнить.
Кто должен запускать серверный процесс и кто клиентские ?
0
0 / 0 / 0
Регистрация: 25.11.2012
Сообщений: 30
23.05.2013, 12:04  [ТС]
Убежденный, запускать буду я и одну и вторую(уже сделал гуи диспетчер который запускает ехе сервера и к число ехе-шок клиентов)
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
23.05.2013, 12:10
Тогда вот что получается. Есть два процесса, запускающихся отдельно,
"третьей силой". В одном процессе создается анонимный канал, а второй к
этому каналу каким-то образом должен подключиться. Как Вы себе это
представляете ? Канал-то анонимный, имени у него нет, хэндл его никому
не передается, как в примере, что я приводил...
1
0 / 0 / 0
Регистрация: 25.11.2012
Сообщений: 30
23.05.2013, 12:16  [ТС]
Тоесть это сделать нереально. Тогда как можно сделать по другому?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
23.05.2013, 12:19
Добавлено через 40 секунд
Цитата Сообщение от Yoshi21 Посмотреть сообщение
Тоесть это сделать нереально.
Реально. Но это будет через пень-колоду.

Цитата Сообщение от Yoshi21 Посмотреть сообщение
Тогда как можно сделать по другому?
Именованный канал.
Либо запускать клиентов из сервера, с наследованием хэндла анонимного канала.
0
0 / 0 / 0
Регистрация: 25.11.2012
Сообщений: 30
23.05.2013, 12:36  [ТС]
Так как пишу курсовую надо именно так. И по заданию анонимные каналы (именоваными я так реализовал) .Напишите пожалуйста пример даже если он карявые.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
23.05.2013, 14:00
Цитата Сообщение от Yoshi21 Посмотреть сообщение
запускать буду я и одну и вторую(уже сделал гуи диспетчер который запускает ехе сервера и к число ехе-шок клиентов)
Можете попробовать так: в GUI-диспетчере создается анонимный канал, один конец
которого отдается серверу, а второй клиенту. И потом они между собой кооперируются.
Других "человечных" вариантов попросту не существует. В текущей постеновке задачи.

Добавлено через 18 минут
Цитата Сообщение от Убежденный Посмотреть сообщение
Можете попробовать так: в GUI-диспетчере создается анонимный канал, один конец
которого отдается серверу, а второй клиенту. И потом они между собой кооперируются.
Правда, я не поручусь, что это будет работать, если закрыть GUI-диспетчер...
0
0 / 0 / 0
Регистрация: 25.11.2012
Сообщений: 30
23.05.2013, 14:07  [ТС]
А если сервер запускает клиентов только не 1 а множество
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
23.05.2013, 14:13
Цитата Сообщение от Yoshi21 Посмотреть сообщение
А если сервер запускает клиентов только не 1 а множество
Если сервер запускает клиентов, тогда он может прокидывать им хэндлы пайпа.
Через STARTUPINFO, как писалось выше, да хоть через командную строку.
Только клиенты должны писать по очереди, а не параллельно, а вот для этого и
можно использовать мьютекс.
1
0 / 0 / 0
Регистрация: 25.11.2012
Сообщений: 30
23.05.2013, 14:49  [ТС]
А как запустить сразу несколько клиентов сервером?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
23.05.2013, 17:13
Ну например, создать событие в несигнальном состоянии, потом запустить нужное
количество процессов, которые ждут на этом событии, а после этого посигналить.
В итоге все копии порожденного процесса начнут работать примерно в одно время.
1
0 / 0 / 0
Регистрация: 25.11.2012
Сообщений: 30
23.05.2013, 18:02  [ТС]
1)Создал событие, процесс запускается вроде по нему посмотрите.
2)Не знаю как теперь запустить больше 1-го процесса.
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
//---------------------
//    C L I E N T
//---------------------
 
#include <iostream>
#include <Windows.h>
 
int main()
{
    using namespace std;
    srand(GetCurrentProcessId());
 
    //"открываем" событие, созданное сервером
    HANDLE hEv = CreateEventA(0, TRUE, FALSE, "READEVENT");
 
    HANDLE hMutex;
    hMutex = OpenMutex(SYNCHRONIZE, FALSE, L"Mutex");
 
    HANDLE const hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 
    //Захватываем мютекс
    WaitForSingleObject(hMutex, INFINITE);
 
    // Записываем в устройство переменную типа int.
    int szBuf[4]={0,0,0,0};
    szBuf[0]=(rand()%5)+1;
    szBuf[1]=(szBuf[0]+rand()%20)*2;
    szBuf[2]=rand()%5;
    szBuf[3]=rand()%5;
 
    DWORD nBytes;
    if(!WriteFile(hStdOutput, &szBuf, sizeof (szBuf), &nBytes, NULL))
    {
        std::cout<<"Error code: "<<GetLastError()<<std::endl;
        return -1;
    };
 
    SetEvent(hEv);
    CloseHandle(hEv);
        CloseHandle(hMutex);
    return EXIT_SUCCESS;
}
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//---------------------
//    S E R V E R
//---------------------
#include <iostream>
#include <Windows.h>
#include <stdio.h>
#include <conio.h>
#include <fstream>
#include <cmath>
using namespace std;
void tab(int start, int end, int step, int funcnum){...}
int main()
{
    SECURITY_ATTRIBUTES sa;
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;
    sa.nLength = sizeof (sa);
 
    HANDLE hReadPipe;
    HANDLE hWritePipe;
    HANDLE hMutex;
    hMutex = CreateMutex(NULL, FALSE, L"DemoMutex");
 
    if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0))
    {
        std::cout<<"Error code: "<<GetLastError()<<std::endl;
        return -1;
    };
 
    //событие для информирования о доступности чтения
    HANDLE hEv = CreateEventA(0, TRUE, FALSE, "READEVENT");
 
    cout << "Server v ochikuvani" << endl;Sleep(500);
    // Заполняем структуру STARTUPINFO для будущего процесса.
    // Подменяем хэндл стандартного вывода на хэндл записи в пайп.
    STARTUPINFOW si;
    GetStartupInfoW(&si);
    si.dwFlags |= STARTF_USESTDHANDLES;
    si.hStdOutput = hWritePipe;
 
    // Запускаем дочерний процесс.
    PROCESS_INFORMATION pi;
    wchar_t pCmdLine[] = {L"cli.exe"}; // Буфер должен быть изменяемым !
 
    if(!CreateProcessW(NULL,
        pCmdLine,
        NULL,
        NULL,
        TRUE, // <--- Наследовать хэндлы ? Да.
        NORMAL_PRIORITY_CLASS,
        NULL,
        NULL,
        &si,
        &pi))
    {
        std::cout<<"Error code: "<<GetLastError()<<std::endl;
        return -1;
    };
    CloseHandle(pi.hProcess);// Закр. хэндл записи - нам он не нужен, а у доч. проц. уже есть его копия.
    CloseHandle(pi.hThread);
 
    //ждем пока клиент запишет данные
    WaitForSingleObject(hEv, INFINITE);
 
    cout<<"z'ednano"<<endl;Sleep(500);
    CloseHandle(hWritePipe);
 
    //Захватываем мютекс
    WaitForSingleObject(hMutex, INFINITE);
 
    cout<<"vstanovlennia na chytannia"<<endl;Sleep(500);
    DWORD nBytes;
    int szBuf[4]={0,0,0,0};
 
    ReleaseMutex(hMutex);
    if(!ReadFile(hReadPipe,szBuf,sizeof(szBuf),&nBytes, NULL))
    {
        std::cout<<"Error code: "<<GetLastError()<<std::endl;
        return -1;
    };
    CloseHandle(hReadPipe);
 
 
    cout<<"otrymyemo dani"<<endl;Sleep(500);
    WaitForSingleObject(pi.hProcess, INFINITE);
 
    for (int i=0;i<4;i++)
           {cout<<szBuf[i]<<endl;Sleep(500);}
 
    tab(szBuf[0],szBuf[1],szBuf[2],szBuf[3]);
    cout<<"Protabul'ovano"<<endl;
 
    CloseHandle(hMutex);
    CloseHandle(hEv);
    return EXIT_SUCCESS;
}
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
23.05.2013, 19:37
Yoshi21, ответы на эти вопросы можно найти в MSDN и в любом учебнике по Win32 API.
Как сделать - я написал выше. Ваша задача - найти описание соответствующих функций,
понять, как они работают и применить их к своему примеру. Желаю удачи !
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.05.2013, 19:37

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

Передача данных с использованием Intent
Добрый день! Не получается перенести текст введённый с одного активити в другой. Код первого активити: Intent intent = new...

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

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

Передача данных с использованием протокола UDP
Всем добра. Владею вб и пхп на хорошо. Но не очень дружу с сшарп. Нужен самый простой пример отправки данных в виде текста на другой...


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

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
ИИ и человечность
kumehtar 21.07.2026
Забавно, что общаясь с ИИ, я замечаю, насколько он высказывается умно, и насколько верит в людей. Он умеет прощать. Он знает как отвечать не обесценивая опыт других людей, даже если сам не верит. Он. . .
Нейтральные знания ..., ... чистая наука. Пока что-то проходит модерацию на Хабре, стоит развить мысль ...
Hrethgir 20.07.2026
К таким радикальным взглядам я конечно в той публикации не приходил, но чтобы скоротать вечер, решил углубиться немного. 1. Почему показания термометра заряжены целью? Цель заложена в самом. . .
Установка нескольких штампов электронной подписи в строго определенных местах файла docx
ВладимирСамохин 19.07.2026
(В!) Работа с Электронной подписью - это неотъемлемая часть современного документооборота. Но что делать, если нужно поставить несколько штампов электронной подписи в строго определенных местах. . .
сукцессия 35. Научная статья о проделанной работе
anaschu 19.07.2026
Написал в формате латекс и пдф
Вангую, что это не пройдёт модерацию, и на неделе я запущу свой сервер.
Hrethgir 19.07.2026
Эта публикация сейчас в песочнице и ждёт приглашения. https:/ / habr. com/ ru/ sandbox/ 295048/ По ссылке 403. Не очень информативно такую ссылку постить. Запись от Usaga размещена Сегодня в 06:46 . . .
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru