воскресенье, 9 января 2011 г.

Неименованные каналы в windows


/* Программа клиент */
#include "stdafx.h"
#include "windows.h"
#include "conio.h"
#include "string.h"
#include "iostream"
#include "vector"
#define STOP -1 // Завершение цикла
using namespace std;
/*!
* Функция для проверки верности байт
*\param byteFirst - первое количество байт
*\param byteSecond - второе количество байт
*\return - 1 - количество байт совпадает, 0 - количество байт не совпадает
*/
bool checkByte(DWORD & byteFirst,DWORD & byteSecond)
{
if(byteFirst!= byteSecond)
return false;
return true;
}
int main(int argc, char* argv[])
{
// Если есть параметры у клиента(дескриптор на чтеление из канала)
if(argc<1)
{
// Завершение программы
cout << "Arrguments not enter" << endl;
_getch();
return -1;
}
int command = 0;
DWORD byteRead; // количество байт на чтение
DWORD byteNeedRead; // реальное количество прочитанах байт
// перевод аргумента из строковой формы в HANDLE
HANDLE hRead = (HANDLE)atoi(argv[0]);
// количесто байт на чтение
byteRead = sizeof(int);
// цикл до команды завершение цикла(-1)
while(command!=STOP)
{
// чтение данных из канала и проверка на верное считывание
if(ReadFile(hRead,(void*)&command,byteRead,&byteNeedRead,NULL) == FALSE || checkByte(byteRead,byteNeedRead) == false || byteNeedRead == 0)
{
// если даные не считались или считались неполностью
cout << "Fail with read" << endl;
_getch();
return -1;
}
// вывод считанных данныхх
cout << command << endl;
}
_getch();
return 0;
}


/* Программа сервер */
#include "stdafx.h"
#include "winsock2.h"
#include "windows.h"
#include "conio.h"
#include "string.h"
#include "iostream"
#include "vector"
#define STOP -1
using namespace std;
/*!
* Функция для проверки верности байт
*\param byteFirst - первое количество байт
*\param byteSecond - второе количество байт
*\return - 1 - количество байт совпадает, 0 - количество байт не совпадает
*/
bool checkByte(DWORD & byteFirst,DWORD & byteSecond)
{
if(byteFirst!= byteSecond)
return false;
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hWrite; // дескриптор для записи
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE hRead; // дескриптор для чтения
int count = 0; // количество цифр для ввода
int *number; // цифры
wchar_t buffer[10]; // буфер для дискриптора
DWORD writeByte; // количество байт которые запишутся в канал
DWORD needWrite; // количество байт которые нужно записать в канал
SECURITY_ATTRIBUTES attr;
attr.bInheritHandle = TRUE; // наследуемый дескриптор
attr.lpSecurityDescriptor = NULL;
attr.nLength = sizeof(SECURITY_ATTRIBUTES);
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Создание неименновоного канала
if(!CreatePipe(&hRead,&hWrite,&attr,1024))
return -1;
// Перевод дескриптора на чтение в строковую форму
_itow((int)hRead,buffer,10);
// Создание нового процесса
// Параметром командной строки является дескриптор на чтение
if(!CreateProcess(L"child.exe",buffer,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi))
{
// в случае ошибка закрытие дескрипторы на чтение и на запись
CloseHandle(hRead);
CloseHandle(hWrite);
printf( "CreateProcess failed (%d)\n", GetLastError() );
_getch();
return -1;
}
// Ввод количество цифр и самих цифр
cout << "Enter count number: ";
scanf("%d", &count);
number = (int*)calloc(sizeof(int),count);
for(int i = 0 ; i < count; i++)
cin >> number[i];
writeByte = sizeof(int); // количество байт которые будут записываться в канал
// Если произошла запись в канал, записалось нужное количество байт и они записались
if(WriteFile(hWrite,(void*)&count,writeByte,&needWrite,NULL) == FALSE || checkByte(writeByte,needWrite) == false || needWrite ==0)
{
// если была ошибка
cout << "Data was break" << endl;
goto exit;
}
// запись чисел в канал и проверка как и в прошлом комментарии
for(int i = 0 ; i < count ; i++)
if(WriteFile(hWrite,(void*)&number[i],writeByte,&needWrite,NULL) == FALSE || checkByte(writeByte,needWrite) == false || needWrite ==0)
{
cout << "Data was break" << endl;
break;
}
// после отправки всех чисел отправка комманды на завершение,так же с проверкой
count = -1;
if(WriteFile(hWrite,(void*)&count,writeByte,&needWrite,NULL) == FALSE || checkByte(writeByte,needWrite) == false || needWrite ==0)
{
cout << "Data was break" << endl;
goto exit;
}
exit:
// Завершение всех процесов и закрытие программы
free(number);
FlushFileBuffers(hRead);
FlushFileBuffers(hWrite);
CloseHandle(hRead);
CloseHandle(hWrite);
_getch();
return 0;
}

Комментариев нет:

Отправить комментарий