Именованные Каналы

  • Автор темы Firefox
  • Дата начала
F

Firefox

#1
Здравствуйте. у меня проблема с переключениями между клиентами. то есть: проблема отключить канал. алгоритм такой: подключается один клиент, поработав с которым, надо его закрыть и открыть другой клиент. вот и получается что, когда закрывается первый клиент, то данные в канале при подключении второго почему-то остаются. то есть при подключении второго клиента, функция ReadFile считывает последние данные которые были в канале перед закрытием первого. сервер у меня только читает. а клиент только пишет.
C++:
//Сервер
//.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;