Russian Qt Forum
Ноябрь 23, 2024, 06:47 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: pipe каналы  (Прочитано 5627 раз)
Firefox
Гость
« : Март 26, 2012, 12:38 »

Добрый день. Хочу сделать передачу данных между процессами через именованные каналы. у меня сервер читает данные которые пишет клиент и в зависимости от данных делает те или иные команды. когда клиент один то все в порядке. но при подключении второго с обоих каналов данные уже не читаются. может я не правильно делаю. подскажите пожалуйста.
класс для подключения канала на сервере:
Код:
//.h
#include <QtGui/QMainWindow>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <QTimer>
#include <QString>
#include <QThread>
#include <QProcess>
#include <QTextCodec>
#define BUFFER_SIZE 512

class channel: public QThread  {
Q_OBJECT
public:
channel();
~channel();

OVERLAPPED StrOverlapp;
OVERLAPPED StrOverlappW;
QString Data_pipe;
bool Flag_ext_proc;
LPCTSTR PipeName;
int N_pipe;
void run();
void createChannel();
//void analize_data(char buff[BUFFER_SIZE]);
void disconnect_pipe();
void WriteChannel();



};

Код:
//.cpp
#include "channel.h"

QString str;
// Флаг успешного создания канала
BOOL   fConnected;
// Идентификатор события
HANDLE hEvent;

// Идентификатор канала Pipe
HANDLE hNamedPipe;

// Имя создаваемого канала Pipe
LPCTSTR  lpszPipeName =L"\\\\.\\pipe\\$cv_r$";
LPCTSTR  lpszPipeName1 =L"\\\\.\\pipe\\$cvc$";
// Буфер для передачи данных через канал
char   szBuf[BUFFER_SIZE];

// Количество байт данных, принятых через канал
DWORD  cbRead;
// Количество байт данных, переданных через канал
DWORD  cbWritten;
bool flag=0,flag_exit=0;
bool flag_read=false;
DWORD BytesTransferred;
struct  Pointer{
HWND CurrWnd[50];
HWND hwnd;
int Lenght;
QStringList ListItem;
QString ProcName[50];

};
QTextCodec* code = QTextCodec::codecForName("CP1251");
channel::channel()
{
Data_pipe="";
Flag_ext_proc=0;
}
channel::~channel()
{
DisconnectNamedPipe(hNamedPipe);
CloseHandle(hNamedPipe);
}
void channel::createChannel()
{
DWORD Ret;
DWORD Pipe;
Flag_ext_proc=0;
if (N_pipe==1)PipeName=lpszPipeName;
if (N_pipe==2)PipeName=lpszPipeName1;
// Создаем канал Pipe, имеющий имя lpszPipeName
hNamedPipe = CreateNamedPipe(
PipeName, // имя канала.
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE |PIPE_READMODE_MESSAGE |PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, // максимальное количество экземпляров канала.
BUFFER_SIZE, // размер выходного буфера по умолчанию.
BUFFER_SIZE, // рахмер входного буфера по умолчанию.
INFINITE, // клиент ждет связь бесконечно долго.
NULL // безопасность по умолчанию.
);

// Если возникла ошибка, выводим ее код и завершаем
// работу приложения
if(hNamedPipe == INVALID_HANDLE_VALUE)
{
str+="CreateNamedPipe: Error %ld\n"+GetLastError();
fprintf(stdout,"CreateNamedPipe: Error %ld\n",
GetLastError());
}

if(!fConnected)
// Ожидаем соединения со стороны клиента
fConnected = ConnectNamedPipe(hNamedPipe, NULL);

// При возникновении ошибки выводим ее код
if(!fConnected)
{
if (GetLastError() != ERROR_IO_PENDING)
{
printf("ConnectNamedPipe for pipe %d failed with",
" error %d\n",  GetLastError());
CloseHandle(hNamedPipe);
return;
}
}
else
{
printf("Server is now running\n");
while(1)
{
bool rez=0;
DWORD BRead;
if(Flag_ext_proc==1)
{
Data_pipe="";
break;

}
rez=ReadFile(hNamedPipe, szBuf,BUFFER_SIZE, &BRead,NULL);
if ( rez ==false)
{
if (GetLastError() != ERROR_IO_PENDING)
{
printf("ReadFile failed with error %d\n",
GetLastError());
}
}
if(strlen(szBuf)>0)
{
fprintf(stdout, szBuf);
analize_data(szBuf);
}


}
}
}

void channel::run()
{
createChannel();         
}
void channel::disconnect_pipe()
{
DisconnectNamedPipe(hNamedPipe);
Data_pipe="";

}
Использование
Код:
channel *chan;
channel *chan1;
chan= new channel();
chan->N_pipe=1;
chan->start();
chan1= new channel();
chan1->N_pipe=2;
chan1->start();
.
.
.
.
.
delete chan;
delete chan1;

Клиентский класс:
Код:
//.h
#include <QString>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <QTimer>
#include <QThread>

class chanel_pipe: public QThread
{
Q_OBJECT
public:
chanel_pipe();
~chanel_pipe();
QTimer *Ttime;
OVERLAPPED OVL;
OVERLAPPED StrOverlapp;
void run();
void write_chanel(char string_ch[20]);

protected:
private slots:

};
Код:
//.cpp
#include "chanel_pipe.h"
#define BUFFER_SIZE 512
// Идентификатор канала Pipe
HANDLE hNamedPipe;
// Идентификатор события
HANDLE hEndWrite;
// Количество байт, переданных через канал
DWORD  cbWritten;

// Количество байт, принятых через канал
DWORD  cbRead;
DWORD BytesTransferred;
// Идентификатор события
HANDLE hEvent;

// Буфер для передачи данных
char   szBuf[BUFFER_SIZE];

chanel_pipe::chanel_pipe()
{

}
chanel_pipe::~chanel_pipe()
{
CloseHandle(hNamedPipe);
}
void chanel_pipe::write_chanel(char string_ch[20])
{ for(int i=0;i<20;i++)szBuf[i]=string_ch[i];

WriteFile(hNamedPipe, szBuf, BUFFER_SIZE,
&cbWritten, NULL);
}
void chanel_pipe::run()
{
hEndWrite=CreateEvent(NULL,TRUE,TRUE,NULL);
OVL.Offset=0;
OVL.OffsetHigh=0;
OVL.hEvent=hEndWrite;
bool PRezWait=WaitNamedPipe( L"\\\\.\\pipe\\$cvc$", NMPWAIT_WAIT_FOREVER );

// Создаем канал с процессом PIPES
hNamedPipe = CreateFile(
L"\\\\.\\pipe\\$cvc$", GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING,0, NULL);

// Если возникла ошибка, выводим ее код и
// завершаем работу приложения
if(hNamedPipe == INVALID_HANDLE_VALUE)
{
fprintf(stdout,"CreateFile: Error %ld\n",
GetLastError());

}
}
Записан
mutineer
Гость
« Ответ #1 : Март 26, 2012, 12:43 »

ммм... вот сервер открывает два канала с разными именами. А клиенты оба открывают один и тот же. так и должно быть?
Записан
Firefox
Гость
« Ответ #2 : Март 26, 2012, 14:01 »

спасибо. уже разобралась. Смеющийся
Записан
mutineer
Гость
« Ответ #3 : Март 26, 2012, 14:34 »

спасибо. уже разобралась. Смеющийся
и что было не так?
Записан
Firefox
Гость
« Ответ #4 : Март 28, 2012, 09:26 »

действительно при подключении разных клиентов должно быть одинаковое имя канала у всех.
Записан
Firefox
Гость
« Ответ #5 : Март 28, 2012, 09:35 »

но теперь у меня есть другая проблема. проблема отключить канал. то есть алгоритм такой: подключается один клиент, поработав с который, надо его закрыть и открыть другой клиент. вот и получается что, когда закрывается первый клиент, то данные в канале при подключении второго почему-то остаются. то есть при подключении второго клиента, функция ReadFile считывает последние данные которые были в канале перед закрытием первого.
использую я это так:
Код:
channel *chan;
chan= new channel();
chan->start();// создаем канал и ждем клиента
if(chan->Data_pipe.left(6)=="reg2")// пришла команда по каналу запустить второго клиента и закрыть первого
{
chan->terminate();
chan->disconnect_pipe();
parametr="rm1 ";
parametr+="0 ";
parametr+=Zakaz+" ";
parametr+=Form_IN2+" ";
parametr+=Form_OUT2+" ";
parametr+=IP_BOR;
k=parametr.toWCharArray(Code_par);
Code_par[k]='\0';
chan->start();
ShellExecute(Handle,L"open",L"reg2.exe",Code_par,NULL,SW_RESTORE);
parametr="taskkill /F /IM ";
parametr+=Tek_regim;
::WinExec(parametr.toAscii(), SW_HIDE);
Tek_regim="reg2.exe";

Записан
Firefox
Гость
« Ответ #6 : Март 28, 2012, 12:50 »

вот как все выглядит полностью, но все равно старые данные остаются:
Код:
//Сервер
//.h
#include <QtGui/QMainWindow>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <QTimer>
#include <QString>
#include <QThread>
#include <QProcess>
#include <QTextCodec>
#define BUFFER_SIZE 512

class channel: public QThread  {
Q_OBJECT
public:
channel();
~channel();

OVERLAPPED StrOverlapp;
OVERLAPPED StrOverlappW;
QString Data_pipe;
bool Flag_ext_proc;
LPCTSTR PipeName;
int N_pipe;
void run();
void createChannel();
void analize_data(char buff[BUFFER_SIZE]);
void disconnect_pipe();

};

//.cpp
#include "channel.h"

QString str;
// Флаг успешного создания канала
BOOL   fConnected;
// Идентификатор события
HANDLE hEvent;

// Идентификатор канала Pipe
HANDLE hNamedPipe;

// Имя создаваемого канала Pipe
LPCTSTR  lpszPipeName =L"\\\\.\\pipe\\$cv_r$";
// Буфер для передачи данных через канал
char   szBuf[BUFFER_SIZE];

// Количество байт данных, принятых через канал
DWORD  cbRead;
// Количество байт данных, переданных через канал
DWORD  cbWritten;
bool flag=0,flag_exit=0;
bool flag_read=false;
DWORD BytesTransferred;
struct  Pointer{
HWND CurrWnd[50];
HWND hwnd;
int Lenght;
QStringList ListItem;
QString ProcName[50];

};
QTextCodec* code = QTextCodec::codecForName("CP1251");
channel::channel()
{
Data_pipe="";
Flag_ext_proc=0;
}
channel::~channel()
{
DisconnectNamedPipe(hNamedPipe);
CloseHandle(hNamedPipe);
}
void channel::createChannel()
{
DWORD Ret;
DWORD Pipe;
// Создаем канал Pipe, имеющий имя lpszPipeName
hNamedPipe = CreateNamedPipe(
lpszPipeName, // имя канала.
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE |PIPE_READMODE_MESSAGE |PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, // максимальное количество экземпляров канала.
BUFFER_SIZE, // размер выходного буфера по умолчанию.
BUFFER_SIZE, // рахмер входного буфера по умолчанию.
INFINITE, // клиент ждет связь бесконечно долго.
NULL // безопасность по умолчанию.
);

// Если возникла ошибка, выводим ее код и завершаем
// работу приложения
if(hNamedPipe == INVALID_HANDLE_VALUE)
{
str+="CreateNamedPipe: Error %ld\n"+GetLastError();
fprintf(stdout,"CreateNamedPipe: Error %ld\n",
GetLastError());
}
if(!fConnected)
// Ожидаем соединения со стороны клиента
fConnected = ConnectNamedPipe(hNamedPipe, NULL);

// При возникновении ошибки выводим ее код
if(!fConnected)
{
if (GetLastError() != ERROR_IO_PENDING)
{
printf("ConnectNamedPipe for pipe %d failed with",
" error %d\n",  GetLastError());
CloseHandle(hNamedPipe);
return;
}
}
else
{
printf("Server is now running\n");
while(1)
{
bool rez=0;
DWORD BRead;
rez=ReadFile(hNamedPipe, szBuf,BUFFER_SIZE, &BRead,NULL);
if ( rez ==false)
{
if (GetLastError() != ERROR_IO_PENDING)
{
printf("ReadFile failed with error %d\n",
GetLastError());
}
}
if(strlen(szBuf)>0)
{
fprintf(stdout, szBuf);
analize_data(szBuf);
if(szBuf[0]=='r')
break;
}
}
DisconnectNamedPipe(hNamedPipe);
CloseHandle(hNamedPipe);
}
}

void channel::run()
{
createChannel();         
}
void channel::analize_data(char buff[BUFFER_SIZE])
{
QString str;
HWND Id_prog=0;
int numW;
for(int i=0;i<BUFFER_SIZE; i++) str+=buff[i];
Data_pipe=str;
 }
void channel::disconnect_pipe()
{
DisconnectNamedPipe(hNamedPipe);
Data_pipe="";
}

// использование
channel *chan;
chan= new channel();
if(chan->Data_pipe.left(4)=="reg2")
{
chan->terminate();
parametr="rm2 ";
parametr+="0 ";
parametr+=Zakaz+" ";
parametr+=Form_IN_2+" ";
parametr+=Form_OUT_2+" ";
parametr+=IP_BOR;
k=parametr.toWCharArray(Code_par);
Code_par[k]='\0';
chan->start();
ShellExecute(Handle,L"open",L"reg2.exe",Code_par,NULL,SW_RESTORE);
parametr="taskkill /F /IM ";
parametr+=Tek_regim;
::WinExec(parametr.toAscii(), SW_HIDE);
Tek_regim="reg2.exe";
}
..
..
..
delete chan;
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.133 секунд. Запросов: 20.