Для студентов згиа специальности 080403 ”Программное обеспечение




НазваниеДля студентов згиа специальности 080403 ”Программное обеспечение
страница9/34
Дата публикации25.02.2013
Размер3.71 Mb.
ТипМетодическое пособие
uchebilka.ru > Информатика > Методическое пособие
1   ...   5   6   7   8   9   10   11   12   ...   34

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

      1. ^ Анонимные каналы

Анонимные каналы в Windows – это полудуплексное (однонаправленное) средство потоковой передачи байтов между родственными процессами (анонимный канал нельзя создать между любыми двумя процессами). Они функционируют в пределах локальной вычислительной системы (не могут работать по сети) и хорошо подходят для перенаправления выходного потока одной программы на вход другой.

Анонимные каналы создаются процессом сервером при помощи функции CreatePipe:

BOOL CreatePipe(

PHANDLE hReadPipe, // описатель для чтения

PHANDLE hWritePipe, // описатель для записи

LPSECURITY_ATTRIBUTES lpPipeAttributes, // атрибуты безопасности

DWORD nSize // размер канала

);

Функция CreatePipe возвращает два описателя (дескриптора) для чтения и записи в канал. После создания канала необходимо передать клиентскому процессу эти дескрипторы (или один из них), что обычно делается с помощью механизма наследования.

Для наследования описателя нужно, чтобы дочерний процесс создавался функцией CreateProcess с флагом наследования TRUE. Предварительно нужно создать наследуемые описатели. Это можно, например, сделать путем явной спецификации параметра bInheritHandle структуры SECURITY_ATTRIBUTES при создании канала.

Другим способом является создание наследуемого дубликата имеющегося описателя при помощи функции DuplicateHandle и последующая передача его создаваемому процессу через командную строку или каким-либо иным образом.

Получив нужный описатель, клиентский процесс, так же как и сервер, может далее взаимодействовать с каналом при помощи функций ReadFile и WriteFile. По окончании работы с каналом оба процесса должны закрыть описатели при помощи функции CloseHandle.

Пример. Программа общения процесса через анонимный канал с самим собой [22].

#include

#include
int main()

{

HANDLE hRead, hWrite;

char BufIn[100], *BufOut = "0123456789";

int BufSize = 100;

int BytesOut = 10, BytesIn = 5, i;

if(!CreatePipe(&hRead, &hWrite, NULL, BufSize))

printf("Create pipe failed.\n");

WriteFile(hWrite, BufOut, BytesOut, &BytesOut, NULL);

printf("Write into pipe %d bytes : ", BytesOut);

for(i=0; i
printf("\n");

ReadFile(hRead, BufIn, BytesIn, &BytesIn, NULL);

printf("Read from pipe %d bytes : ", BytesIn);

for(i=0; i<5;i++) printf("%c",BufIn[i]);

return 0;

}

В приведенной программе создается анонимный канал, в него записывается строка цифр, затем часть этой строки читается и выводится на экран.

      1. ^ Именованные каналы

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

Каналы должны иметь уникальные в рамках сети имена в соответствии с правилами именования ресурсов в сетях Windows (Universal Naming Convention, UNC), например, \\ServerName\pipe\PipeName. Для общения внутри одного компьютера имя записывается в форме \\.\pipe\PipeName, где "." обозначает локальную машину. Слово "pipe" в составе имени фиксировано, а PipeName - имя, задаваемое пользователем. Эти имена, подобно именам открытых файлов, не являются именами объектов. Они относятся к пространству имен под управлением драйверов файловых систем именованных каналов (\Winnt\System32\Drivers\Npfs.sys), привязанному к специальному объекту устройству \Device\NamedPipe, на которое есть ссылка в каталоге глобальных имен объектов \??\Pipe (эти последние имена "видит" утилита WinObj).

Имена созданных именованных каналов можно перечислить с помощью свободно распространяемой утилиты pipelist с сайта www.sysinternals.com. Поскольку имена каналов интегрированы в общую структуру имен объектов, приложения могут открывать именованные каналы с помощью функции CreateFile и взаимодействовать с ними через функции ReadFile и WriteFile.

^ Использование именованных каналов

Сервер создает именованный канал при помощи функции CreateNamedPipe:

HANDLE CreateNamedPipe(

LPCTSTR lpszPipeName,

DWORD fdwOpenMode,

DWORD fdw PipeMode,

DWORD nMaxInstances,

DWORD cbOutBuf,

DWORD cbInBuf,

DWORD dwTimeOut,

LPSECURITY_ATTRIBUTES lpsa

);

Параметр обозначает имя канала в форме \\.\pipe\[путь]имя_канала. Точка обозначает локальную машину; иначе говоря, создать канал на удаленной машине нельзя. Параметр fdwOpenMode имеет одно из следующих значений:

  • PIPE_ACCESS_DUPLEX – двунаправленный режим, эквивалентно комбинации

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

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

После вызова CreateNamedPipe сервер выполняет вызов ConnectNamedPipe и ждет отклика от клиентов, которые соединяются с каналом при помощи функции CreateFile или CallNamedPipe, указывая при вызове имя созданного сервером канала. Легальный клиент получает описатель, представляющий клиентскую сторону именованного канала, и работа серверной функции ConnectNamedPipe на этом завершается.

После того как соединение по именованному каналу установлено, клиент и сервер могут использовать его для чтения и записи данных через Win32-функции ReadFile и WritePile.

Пример. Общение двух процессов через именованный канал [22].

Сервер.

#include

#include
void main()

{

PROCESS_INFORMATION piProcInfo;

^ STARTUPINFO SI;

char * ClientName = "client.exe";

HANDLE hPipe;

LPTSTR PipeName = TEXT("\\\\.\\pipe\\MyPipe");

char Buff[255];

DWORD iNumBytesToRead = 255, i;

ZeroMemory(&SI, sizeof(STARTUPINFO));

SI.cb = sizeof(STARTUPINFO);

ZeroMemory(&piProcInfo, sizeof(piProcInfo));
hPipe = CreateNamedPipe(

PipeName, // имя канала

PIPE_ACCESS_DUPLEX, // чтение и запись из канала

PIPE_TYPE_MESSAGE | // передача сообщений по каналу

PIPE_READMODE_MESSAGE | // режим чтения сообщений

PIPE_WAIT, // синхронная передача сообщений

PIPE_UNLIMITED_INSTANCES, // число экземпляров канала

4096, // размер выходного буфера

4096, // размер входного буфера

NMPWAIT_USE_DEFAULT_WAIT, // тайм-аут клиента

NULL); // защита по умолчанию

if (hPipe == INVALID_HANDLE_VALUE)

{

printf("CreatePipe failed: error code %d\n", (int)GetLastError());

return;

}

if((CreateProcess(NULL, ClientName, NULL, NULL, FALSE, 0, NULL, NULL, &SI, &piProcInfo))==0)

{

printf("create client process: error code %d\n", (int)GetLastError());

return;

}

if((ConnectNamedPipe(hPipe, NULL))==0)

{

printf("client could not connect\n");

return;

}

ReadFile(hPipe, Buff, iNumBytesToRead, &iNumBytesToRead, NULL);

for(i=0; i
}

Клиент.

#include

#include
void main()

{

HANDLE hPipe;

LPTSTR PipeName = TEXT("\\\\.\\pipe\\MyPipe");

DWORD NumBytesToWrite;

char Buff[] = "Message from Client";
hPipe = CreateFile(

PipeName, // имя канала

GENERIC_READ | // чтение и запись в канал

GENERIC_WRITE,

0, // нет разделяемых операций

NULL, // защита по умолчанию

OPEN_EXISTING, // открытие существующего канала

0, // атрибуты по умолчанию

NULL); // нет дополнительных атрибутов
WriteFile(hPipe, Buff, strlen(Buff), &NumBytesToWrite, NULL);

}

В данном примере сервер создает канал, затем запускает процесс-клиент и ждет соединения. Далее он читает сообщение, посланное клиентом.

Помимо перечисленных выше система представляет еще ряд полезных функций для работы с именованными каналами. Для копирования данных из именованного канала без удаления их из канала используется функция PeekNamedPipe. Функция TransactNamedPipe применяется для объединения операций чтения и записи в канал в одну операцию, которая называется транзакцией. Имеются информационные функции для определения состояния канала, например, GetNamedPipeHandleState или GetNamedPipeInfo. Полный перечень находится в MSDN.


    1. ^ Почтовые ячейки

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

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

Однако почтовые ячейки поддерживают широковещательную передачу сообщений одновременно нескольким адресатам в сети.

Для использования почтовых ячеек нужно выполнить ряд операций.

Каждый сервер (получатель) создает почтовую ячейку, используя функцию CreateMailslot:

HANDLE CreateMailslot(

LPCTSTR lpszName,

DWORD cbMaxMsg, //макс.размер (в байтах) сообщений

DWORD dwReadTimeout,

LPSECURITY_ATTRIBUTES lpsa

);

Параметр указывает на имя почтовой ячейки в форме \\.\mailslot\[путь]имя. Символ ”.” показывает, что почтовая ячейка создается на локальной машине.

Сервер ожидает приема сообщений из почтовой ячейки, вызвав ReadFile.

Клиент (отправитель) должен открыть почтовую ячейку функцией CreateFile и может использовать следующие формы имен:

  • \\.\mailslot\[путь]имя – возвращает дескриптор для локальной почтовой ячейки;

  • \\имя_компьютера\mailslot\[путь]имя – возвращает дескриптор почтовой ячейки на указанной машине;

  • \\имя_домена\mailslot\[путь]имя – возвращает дескриптор, представляющий все почтовые ячейки на машинах домена.

Операция открытия завершится неудачно (имя не будет найдено), если ожидающих получателей нет.

Клиент посылает сообщения с помощью функции WriteFile.

Пример [4]. Серийные номера. Предположим, что мы хотим разработать механизм защиты вашей программы от несанкционированного копирования. Допустим, в любой момент времени пользователям сети разрешается запускать только одну копию вашей программы. Каждая копия широковещательно передает собственный серийный номер и имя компьютера, на котором она запущена.

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

Листинг 2.5 Серийные номера

#include ”stdafx.h”

#include

#include “process.h”

int sn = 1;//серийный номер

char machname[128];

//Эта функция работает в отдельном потоке и слушает почтовую ячейку

void checksn(void *h)

{

HANDLE mh = (HANDLE)h;

unsigned long n;

char imsg[128], *p;

while(1){

if(ReadFile(mh, imsg, sizeof(imsg), &n, NULL)){

p = strchr(imsg, ‘\n’);

if(!p) continue; //bad packet

*p = ‘\0’;

P = strchr(imsg, ‘:’);

if(!p) continue; //bad packet

*p = ‘\0’;

//проверка на сообщения от текущего экземпляра программы

if(!stricmp(machname, imsg)) continue;

//сообщение поступило с другого компьютера

if(sn == atoi(p+1))

{

//Наш серийный номер используется кем-то другим

printf(“Launched don’t authorized copy of program.\n”);

exit(100);

}

}

}

}

int main(int argc, char* argv[])

{

unsigned long n;

//В целях отладки мы читаем серийный номер из командной строки

if(argc>1)sn=atoi(argv[1]);

SECURITY_ATTRIBUTES sa;

SECURITY_DESCRIPTOR sd;

//разрешение полного доступа

InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);

sa.bInheritHandle=FALSE;

sa.lpSecurityDescriptor=&sd;

sa.nLength=sizeof(sa);

unsigned long sz=sizeof(machname);

GetComputerName(machname, &sz);

//Создаем почтовую ячейку для приема широковещательных сообщений

HANDLE h=CreateMailslot(“\\\\.\\mailslot\\serial.box”,

128,MAILSLOT_WAIT_FOREVER, &sa);

if(!h){printf(“Cannot open mailslot\n”); exit(1);}

HANDLE w=CreateFile(“\\\\*\\mailslot\\serial.box”,GENERIC_WRITE,0, NULL, OPEN_ALWAYS, 0, NULL);

if(!w){printf(“Cannot open mailslot in broadcasting mode\n”); exit(2);}

//начинаем слежение за другими серийными номерами

_beginthread(checksn,0,(void*)h);

//широковещательно передаем собственный серийный номер

char msg[128];

wsprintf(msg,”%s:%d\n”,machname,sn);

WriteFile(w,(LPCVOID)msg,strlen(msg),&n,NULL);

CloseHandle(w);

//приступаем к выполнению основной работы

printf(“Work start. . .\n”);

while(1){

//

}

return 0;

}

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



    1. ^ Формат исполняемого PE-файла

В операционных системах Windows существует несколько типов исполняемых файлов. Типы файлов различаются по расширению файла, а также по сигнатуре (определенной последовательности байтов, находящихся по определенным смещениям в теле исполняемого файла). Все сигнатуры представлены в таблице 2.8 [8]:

Табл. 2.8 Сигнатуры исполняемых файлов

Сигнатура

Значение

Описание

IMAGE_DOS_SIGNATURE

0x5A4D

MZ

IMAGE_OS2_SIGNATURE

0x454E

NE

IMAGE_OS2_SIGNATURE_LE

0x454C

LE

IMAGE_VXD_SIGNATURE

0x454C

LE

IMAGE_NT_SIGNATURE

0x00004550

PE00


Мы будем рассматривать (упрощенно) только формат PE-файла, сигнатура которого представлена в таблице последней строкой. Формат исполняемого файла полностью документирован в файле winnt.h Windows SDK.
1   ...   5   6   7   8   9   10   11   12   ...   34

Похожие:

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания к лабораторному практикуму для студентов згиа...
Методические указания к лабораторному практикуму для студентов згиа специальности 080403 «Программное обеспечение автоматизированных...

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания для студентов специальности 080403
Згиа [8, 10] и других вузов [4]. Наиболее полно описаны курсовые, дипломные и квалификационные работы, однако большинство положений...

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания к курсовой работе по дисциплине «Системное...
Методические указания к курсовой работе по дисциплине «Системное программирование и операционные системы» для студентов специальности...

Для студентов згиа специальности 080403 ”Программное обеспечение iconПравила использования программного обеспечения в рамках программы...
Используя программное обеспечение вы тем самым подтверждаете свое согласие придерживаться этих правил. Если вы не согласны, не используйте...

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания по выполнению лабораторных работ по курсу “
Информационные управляющие системы и технологии, 080403 – Программное обеспечение автоматизированных систем

Для студентов згиа специальности 080403 ”Программное обеспечение iconКлассификация программного обеспечения
В отличие от аппаратного обеспечения, программы, которые выполняются на нем, неосязаемы и классифицируются как программное обеспечение....

Для студентов згиа специальности 080403 ”Программное обеспечение iconКурсовая работа выполняется на основании 'Задания на курсовую работу'...
Целью курсовой работы является закрепление практических навыков самостоятельной постановки и решения задачи обработки данных с помощью...

Для студентов згиа специальности 080403 ”Программное обеспечение icon1. Классификация программного обеспечения
Назначением ЭВМ является выполнение программ. Программа содержит команды, определяющие порядок действии компьютера. Совокупность...

Для студентов згиа специальности 080403 ”Программное обеспечение iconОпорный конспект лекций по дисциплине Компьютерная графика для специальности...
Тема. Основные понятия компьютерной графики. Аппаратное и программное обеспечение

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания и задание к выполнению курсового проекта по...
Методические указания и задание к выполнению курсового проекта по дисциплине «Алгоритмическое и программное обеспечение электротехнических...

Вы можете разместить ссылку на наш сайт:
Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
uchebilka.ru
Главная страница


<