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

Анонимные каналы. Петля?

01.12.2011, 16:17. Показов 6388. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет всем.
Есть задание: при помощи анонимных каналов наладить передачу данных между двумя процессами по схеме 1->2, 2->1. Есть у кого-нибудь идеи или подобные примерчики? Просто я не могу уложить в голову, как это сделать, ведь используется стандартный ввод-вывод. Получается петля без точки ввода же.
Разъясните.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.12.2011, 16:17
Ответы с готовыми решениями:

Анонимные именованные каналы
Подскажите, как изменить этот пример:...

Анонимные каналы "Системное программирование в Windows" (А. Побегайло)
Здравствуйте. Читаю книгу "Системное программирование в Windows" (А. Побегайло). Добрался до 15...

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

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

9
53 / 53 / 8
Регистрация: 21.03.2009
Сообщений: 371
01.12.2011, 20:52 2
При использовании анонимного канала выполняется ряд действий
1)Сервер создает анонимный канал.
2)Сервер создает дочерний процесс и передает ему дескриптор канала
3)По каналу производится синхронная передача данных
4)Для обмена данными используются функции работы с файлом
В кратце код сервера
C++
1
2
3
4
5
6
7
8
9
10
11
CreatePipe(PHANDLE hRead,//дескриптор для чтения
PHANDLE hWrite,//для записи
LPSECYRITY_ATTRIBUTES lpsec,//здесь сделать дескриптор наследуемым 
//lpsec->bInheriteHandle=TRUE
DWORD size);
//Возможный способ передачи дескриптора.Подготавливаем дескр чтения для передачи
sprintf(buf,"path_to_childprocess %d"(int)hRead);
CreateProcess(...,buf,...);
//Пишим в канал
WriteFile(hWrite,...);
//закончили
код клиента
C++
1
2
HANDLE hr=atoi(argv[1]);
ReadFile(hr,...);
С помощью какого нибудь объекта синхронизации можно предусмотреть чтобы считка не произошла раньше записи.В вашем случае надо передать дочернему процессу оба дескриптора
0
2 / 2 / 0
Регистрация: 05.10.2010
Сообщений: 37
01.12.2011, 22:03  [ТС] 3
Спасибо, что отозвались. Возникло несколько вопросов. Вполне вероятно, глупых.
1. Но ведь все равно нужно два канала, так? Анонимные же вроде поддерживают передачу только в один конец.
2. Не очень знаком с параметрами argc, argv. Можно чуточку подробнее?
3. Каким образом передать клиенту два дескриптора, ведь, насколько я понимаю, atoi переводит строку в символ до тех пор, пока не встретит символ, отличный от цифры.
0
53 / 53 / 8
Регистрация: 21.03.2009
Сообщений: 371
01.12.2011, 22:34 4
Канал 1 а используется 2 дескриптора один для чтения другой для записи.один дескриптор только для чтения второй только для записи это и есть в одном направлении
argv -это массив символов
C++
1
2
3
4
5
char buf[256];
sprintf(buf,"Path:\\name.exe %d %d",(int)handleRead,(int)handleWrite);
//child process
HANDLE hread=atoi(argv[1]);
HANDLE hwrite=atoi(argv[2]);
А вообще хорошая книга Александр Побегайло Системное программирование в Windows
0
2 / 2 / 0
Регистрация: 05.10.2010
Сообщений: 37
02.12.2011, 00:11  [ТС] 5
Цитата Сообщение от lavan Посмотреть сообщение
//child process
HANDLE hread=atoi(argv[1]);
При попытке такого определения студия говорит, что нельзя присвоить значение типа int сущности HANDLE.
0
53 / 53 / 8
Регистрация: 21.03.2009
Сообщений: 371
02.12.2011, 09:39 6
Все правильно говорит,вы же сохраняете int а присваиваете HANDLE-у.Надо делать приведение типов
C++
1
HANDLE ht=(HANDLE)atoi(argv[1]);
0
2 / 2 / 0
Регистрация: 05.10.2010
Сообщений: 37
02.12.2011, 14:45  [ТС] 7
Я и думал так сделать, но разве есть приведение int -> HANDLE?
Сейчас попробую.
0
2 / 2 / 0
Регистрация: 05.10.2010
Сообщений: 37
03.12.2011, 16:36  [ТС] 8
Вроде, сделал все, как вы говорили, но процесс-потомок не хочет читать строку. Сервер должен принимать строку от пользователя и передавать ее клиенту, а клиент должен ее же просто возвращать.
Сервер:
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
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
using namespace std;
 
HANDLE hRead, hWrite;
HANDLE Proc;
HANDLE hEvent1, hEvent2;
BOOL fSuccess;
DWORD dwRead, dwWritten;
char str[256];
 
int main ()
{
    char buf[256];
    char Ev1[] = "MyEvent1";
    char Ev2[] = "MyEvent2";
    SECURITY_ATTRIBUTES saAttr;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;
    if (!CreatePipe (&hRead, &hWrite, &saAttr, 512) )
    {
        printf ("Error while creating pipe\n");
        getch ();
        return 0;
    }
    if ((hEvent1 = CreateEvent (&saAttr, FALSE, FALSE, Ev1)) == NULL )
    {
        printf ("Error while creating first event\n");
        getch ();
        return 1;
    }
 
    if ((hEvent2 = CreateEvent (&saAttr, FALSE, FALSE, Ev2)) == NULL )
    {
        printf ("Error while creating second event\n");
        getch();
        return 2;
    }
 
    sprintf (buf, "PipeA.exe %d %d", (int)hRead, (int)hWrite);
 
    ZeroMemory (&si, sizeof (si));
    si.cb = sizeof(si);
 
    ZeroMemory (&pi, sizeof(pi));
    if (!CreateProcess (NULL, buf, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi) )
    {
        printf ("Error while starting child process\n");
        getch ();
        return 3;
    }
 
    while (1)
    {
        cout << "Input the string: ";
        cin >> str;
        fSuccess = WriteFile (hWrite, str, dwRead, &dwWritten, NULL);
        if (!fSuccess)
            break;
        SetEvent(hEvent2);
        WaitForSingleObject(hEvent1, INFINITE);
        cout << "Reading file..." << endl;
        fSuccess = ReadFile (hRead, str, 256, &dwRead, NULL);
        if (!fSuccess)
            break;
        cout << str;
    }
    ExitProcess (0);
    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
#include <windows.h>
#include <iostream>
#include <conio.h>
 
using namespace std;
 
char str[256], Ev1[] = "MyEvent1", 
               Ev2[] = "MyEvent2";
DWORD dwRead, dwWritten;
HANDLE hRead, hWrite;
HANDLE hEvent1, hEvent2;
BOOL fSuccess;
 
int main (int argc, char *argv[])
{
    hEvent1 = OpenEvent (EVENT_ALL_ACCESS, TRUE, Ev1);
    hEvent2 = OpenEvent (EVENT_ALL_ACCESS, TRUE, Ev2);
 
    if ( (!hEvent1) || (!hEvent2) )
    {
        printf ("Error while opening event\n");
        getch ();
        return 0;
    }
 
    hRead = (HANDLE)(atoi(argv[1]));
    hWrite = (HANDLE)(atoi(argv[2]));
 
    while (1)
    {
        WaitForSingleObject (hEvent2, INFINITE);
        cout << "Reading string..." << endl;
        fSuccess = ReadFile (hRead, str, 256, &dwRead, NULL);
        if (!fSuccess)
            break;
        cout << str;
        cout << "Writing string..." << endl;
        fSuccess = WriteFile (hWrite, str, dwRead, &dwWritten, NULL);
        if (!fSuccess)
            break;
        SetEvent (hEvent1);
    }
    ExitProcess (0);
    return 0;
}
С хэндлами, видать-таки, что-то не то.
Кстати, не помню. Кажется, где-то читал, что хэндлы канала для каждого процесса уникальны и нужно использовать DuplicateHandle.
0
53 / 53 / 8
Регистрация: 21.03.2009
Сообщений: 371
03.12.2011, 17:34 9
зря вы не хотите скачать книгу которую я вам посоветовал! С хенделами все в порядке,а с инициализацией переменных нет
C++
1
fSuccess = WriteFile (hWrite, str, dwRead, &dwWritten, NULL);
а где вы инициализировали dwRead? здесь вы сказали "запиши 0 байт"
1
2 / 2 / 0
Регистрация: 05.10.2010
Сообщений: 37
03.12.2011, 17:44  [ТС] 10
Уже скачал, только, пардон, забыл про нее
Спасибо, все заработало.
0
03.12.2011, 17:44
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.12.2011, 17:44
Помогаю со студенческими работами здесь

Общение между процессами через анонимные каналы
Нужно посчитать кое-что по формуле При этом все элементарные арифметические действия сделать в...

Петля ?
Это петля ? Между sw3 и sw4 ?

петля в сети
всем доброго времени суток! проблема такая, есть большая сеть состоящая из НЕ управляемых...

20 mA токовая петля
Привет всем. Понадобилось тут мне скопировать один буржуйский адаптер 20мА токовой петли. Схему...


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

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