Структурные элементы "ВВЕДЕНИЕ", "РЕФЕРАТ", "СОДЕРЖАНИЕ", "ПЕРЕЧЕНЬ УСЛОВНЫХ ОБОЗНАЧЕНИЙ, СИМВОЛОВ, ЕДИНИЦ, СОКРАЩЕНИЙ И ТЕРМИНОВ ", "ВЫВОДЫ", "РЕКОМЕНДАЦИИ", "ПЕРЕЧЕНЬ ССЫЛОК " не нумеруют, а их наименования служат заголовками структурных элементов и размещают по центру страницы.
Текст пояснительной записки разбивается на разделы. Разделы могут разбиваться на подразделы. Подразделы могут разбиваться на пункты. Пункты, в свою очередь, разбиваются на подпункты.
Каждой структурной единице присваивается номер, который записывается арабскими цифрами. Разделы нумеруются целыми числами, начиная с 1. Точка в конце номера не ставится. Номер подраздела состоит из номера раздела и номера подраздела в разделе, разделенных точкой. Номер пункта состоит из номера раздела, номера подраздела в разделе и номера пункта в подразделе, разделенных точками. Номер подпункта состоит из номера раздела, номера подраздела в разделе, номера пункта в подразделе и номера подпункта в пункте, разделенных точками.
Заголовки разделов записываются заглавными буквами, полужирным шрифтом и размещаются по центру страницы. Заголовки подразделов, пунктов и подпунктов записываются с абзацного отступа, обычным шрифтом. Переносы в заголовках не допускаются. Если заголовок оказывается в конце страницы, то вместе с этим заголовком на данной странице должно быть не менее двух строк последующего текста. В противном случае заголовок переносится на следующую страницу. Заголовок должен отделяться от предыдущего и последующего текста расстоянием не менее 0.5 высоты строки.
Примеры заголовков:
ОБСЛЕДОВАНИЕ ОБЪЕКТА
1.1 Общие сведения
1.1.1 Текущее состояние
1.1.1.1 Переход в исходное состояние
Нумеровать страницы проекта следует арабскими цифрами, соблюдая сквозную нумерацию по всему тексту. Номер страницы проставляют в правом верхнем углу страницы без точки. Титульный лист включают в общую нумерацию, но номер страницы на нем не ставится. Иллюстрации и таблицы, выполненные на отдельных страницах, включают в общую нумерацию.
Иллюстрации
Иллюстрации (чертежи, рисунки, графики, схемы, диаграммы, фотоснимки) следует располагать в проекте непосредственно после текста, в котором они упоминаются впервые или на следующей странице. Количество и содержание иллюстраций должны обеспечивать чтение и понимание курсовой работы. На все иллюстрации должны быть даны ссылки в тексте.
Чертежи, схемы, рисунки, графики, диаграммы должны соответствовать требованиям ЕСКД и ЕСПД. Иллюстрации могут иметь названия, которые размещаются под ними. Поясняющие данные размещают под иллюстрацией. Иллюстрации обозначают словом «Рисунок» и нумеруют арабскими цифрами в пределах раздела. Номер состоит из номера раздела и номера рисунка в разделе, разделенных точкой, например, 3.2. Нумеруется даже одна иллюстрация. Название иллюстрации отделяется от номера дефисом “-”. Например, “Рисунок 3.1 - Схема размещения”.
Если иллюстрация выполняется на нескольких листах, то название иллюстрации помещают на первом листе, например, «Рисунок 4.2, лист 1 – Схема алгоритма процедуры ввода». На последующих листах название не пишется, указывается номер рисунка и номер листа: «Рисунок 4.2, лист 2», «Рисунок 4.2, лист 3» и т.д.
Таблицы
Таблицы следует располагать непосредственно после текста, в котором они упоминаются. Таблицы обозначают словом «Таблица», за которым следует номер. Номер состоит из номера раздела и номера подраздела, разделенных точкой. После номера через дефис записывается название таблицы с большой буквы. Обозначение таблицы записывается с абзаца. Например:
Таблица 2.1- Параметры процедуры.
Нумеруется даже одна таблица.
Таблицы допускаются переносить на следующие страницы, при этом допускается головку и боковые колонки не повторять, а приводить только номера строк и граф. На последующих страницах пишут «Продолжение таблицы …» с указанием номера, но без названия. Например, «Продолжение таблицы 2.1»
Формулы и уравнения
Формулы и уравнения располагают непосредственно после текста, в котором они упоминаются, посредине страницы. Выше и ниже формулы или уравнения необходимо оставлять не менее 0.5 высоты строки. Формулы следует нумеровать порядковой нумерацией в пределах раздела. Номер формулы состоит из номера раздела и порядкового номера формулы в разделе в скобках, например, (3.1). Номер располагают на уровне формулы в крайнем правом положении строки. Например:
X:=z+(b-c)*7.3; (3.1)
Пояснения значений каждого символа следует приводить непосредственно под формулой в той последовательности, как они даны в формуле. Первую строку пояснений следует начинать с абзацного отступа словом «где» без двоеточия. Пояснения каждого символа следует начинать с новой строки.
Перечисления
Перед перечислением становят двоеточие. Допускается два уровня перечисления. На первом уровне перед каждой позицией перечисления следует ставить либо строчную букву украинского алфавита со скобкой, либо – дефис “-“. Если внутри пункта первого уровня перечисления тоже надо выполнить перечисление, то для этого следует использовать арабские цифры с круглой скобкой. Перечисления первого уровня записываются строчными буквами с абзацного отступа, второй уровень - с отступом относительно местоположения начала перечислений первого уровня. Например:
- это перечисление первого уровня:
1) а это перечисление второго уровня;
2) продолжение перечисления второго уровня;
- снова перечисление первого уровня:
1) а теперь снова второго уровня;
2) продолжение второго уровня…
Ссылки
Для оформления ссылок на элементы пояснительной записки должны соблюдаться следующие требования.
Для ссылки на иллюстрацию в тексте пояснительной записки используется слово «рисунок», за которым указывается номер рисунка. Например, «на рисунке 4.3 приведена схема алгоритма».
Для ссылки на таблицу в тексте пояснительной записки используется слово «таблица», за которым указывается номер таблицы. Например, «в таблице 2.7 приведены данные экспериментов».
Для ссылки на литературный источник в тексте пояснительной записки используются квадратные скобки, внутри которых записывается номер этого источника в перечне ссылок. Например, «из данных, приведенных в [3] следует …» или «анализ данных из [7 – 12] показывает…»
Приложения
Приложения следует оформлять как продолжение пояснительной записки на ее последующих страницах. Каждое приложение начинается с новой страницы и обозначается словом «ПРИЛОЖЕНИЕ» и большой буквой украинского алфавита за исключением Є, З, I, Й, Щ, Ч, Ь, например, «ПРИЛОЖЕНИЕ А». Это обозначение приложения должно располагаться в первой строке и по центру страницы.
Приложение должно иметь заголовок, напечатанный вверху в следующей строке за обозначением строчными буквами с первой прописной и расположенный по центру страницы.
Приложения должны иметь общую с основной частью проекта сквозную нумерацию страниц.
При необходимости текст приложения может быть разделен на разделы, подразделы, пункты и подпункты, которые следует нумеровать в пределах приложения аналогично нумерации основной части, но с добавлением буквы, обозначающий приложение, например, А.1.3.3.1.
Иллюстрации, формулы и таблицы нумеруются в пределах приложения, аналогично основному тексту, но с добавлением буквы приложения, например, «Рисунок А.3», «Таблица А.3», формула (А.2).
Нумеруются даже одна иллюстрация, формула или таблица.
Перечисления, примечания и ссылки в приложениях выполняют так же как в основном тексте.
Источники, цитируемые только в приложении, оформляются отдельным перечнем в конце приложения по общим правилам.
Перечень ссылок
1. Таненбаум Э. Современные операционные системы. 3-изд. – СПб.: Питер, 2011
2. Руссинович М., Соломон Д. Внутреннее устройство Microsoft Windows: Windows Server 2003, Windows XP и Windows 2000. - СПб.: Питер, 2008
3. Рязанцев О.І., Ларгіна А. М. Організація обчислювальних процесів в комп’ютерних системах: Навчальний посібник.- Луганськ: Вид-во СНУ ім В. Даля, 2006. –608с..
4. Солдатов В. П. Программирование драйверов Windows. Изд. 2-е, перераб. и доп. – М.: ООО “Бином – Пресс”, 2004г.-480с.: ил.
5. Рихтер Дж. Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64-разрядной версии Windows/Пер, англ - 4-е изд. - СПб; Питер; М.: Издательско-торговый дом "Русская Редакция", 2001. - 752 с.; ил
6. Щупак Ю. А. Win32 API. Эффективная разработка приложений. - Питер 2007-572с.
7. Петзольд Ч. Программирование под Windows 95. В двух книгах: BHV – Санкт – Петербург, 1997.
8. Олифер В.Г., Олифер Н.А. Сетевые операционные системы. – СПб.: Питер, 2009
9. Дейтел Х.М., Дейтел П.Дж., Чофес Д.Р. Операционные системы.- М.: Изд. Бином, 2009
Приложение А
Титульный лист курсовой работы
Форма № Н-6.01
ТЕХНОЛОГІЧНИЙ ІНСТИТУТ
СХІДНОУКРАЇНСЬКОГО НАЦІОНАЛЬНОГО УНІВЕРСИТЕТУ
імені ВОЛОДИМИРА ДАЛЯ
(м. Сєверодонецьк)
Кафедра_______ комп’ютерної інженерії _______
(повна назва кафедри)
КУРСОВИЙ ПРОЕКТ (РОБОТА)
з ________________ Системного програмного забезпечення _________________
(назва дисципліни)
на тему:___ Розроблення програмних додатків за технологією «клієнт-сервер».
Метод комунікації – ____________________________________________
студента (ки) _____ курсу __ 3 _ групи__ КІ-11 __
напряму підготовки_____ 6.050102 «Комп'ютерна інженерія» __________
(шифр і назва напряму підготовки)
спеціальності _________________________________________________________
(шифр і назва спеціальності)
___________________________ ___________
(прізвище та ініціали) (підпис)
Керівник проекту
____________________________ ____________
(посада, вчене звання, науковий ступінь, прізвище та ініціали) (підпис)
Результати захисту:
Національна шкала _______
Кількість балів: __________
Оцінка: ECTS ___________
Члени комісії:
_________________________ ________
(прізвище та ініціали) (підпис)
________________________ ________
(прізвище та ініціали) (підпис)
_________________________ ________
(прізвище та ініціали) (підпис)
Дата_________
Сєверодонецьк - 20 __
Приложение Б
Р Е Ф Е Р А Т
Пояснительная записка к курсовой работе: 31 с., 5 рис., 4 табл., 18 источников.
Объект разработки - подсистема учета результатов соревнований.
Цель работы: разработка приложений на платформе Win32 для исследования взаимодействия между процессами через сокеты.
В курсовой работе применяются проектирование «сверху - вниз» и событийное программирование.
В курсовой работе выполняется разработка программных приложений на платформе Win32 в среде Microsoft Visual Studio, использующие для межпроцессного взаимодействия сокеты.
Выполнено определение области применения, достоинств и недостатков архитектуры «клиент-сервер»; сделан обзор системных средств коммуникации и синхронизации процессов.
Разработан менюориентированный пользовательский интерфейс. Выполнена отладка приложения.
Результаты проектирования используются для внедрения в учебный процесс на факультете КТ в ТИ (г. Северодонецк).
WIN32 API, СОКЕТ, ПРОЦЕССЫ, СОБЫТИЯ, ПОРТ, СИНХРОНИЗАЦИЯ ПРОЦЕССОВ, АЛГОРИТМ, ПРОГРАММА.
Приложение В
Пример задания основных функций приложения-сервера с отображением файла на память
//объявления переменных и объектов
#include "stdafx.h"
#include "MapServer.h"
#include <stdio.h>
#include <process.h>
#include <wchar.h>
#include <sstream>
#define MAX_LOADSTRING 100
#define BUF_SIZE 1024
LPCSTR nameMutex = "Global\\MapMutex";
LPTSTR nameEvent = L"Global\\MapEvent";
HANDLE hServerMutex; // дескриптор мьютекса на доступ к буферу памяти
unsigned uThreadIDs[2];
HANDLE hThreads[2];
BOOL Working=true;
HANDLE hMapFile;
static HWND hwndEdit;
struct D{
TCHAR Buf[1024];
};
D* lpD;
//--------------------------------------------------
unsigned __stdcall VvodThreadFunc(void * arg) // Поток ожидания данных от клиентов
{
while (Working)
{
WaitForSingleObject(hEventVvod,INFINITE); // Ждем своего события
WaitForSingleObject(hServerMutex,INFINITE); // Ждем доступа к памяти
//данные готовы, вывод на экран
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)lpD->Buf);
ReleaseMutex(hServerMutex); // Разрешаем записывать в общую память
}
_endthreadex(0);
return 0;
};
//---------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR ss[80];
switch (message)
{
case WM_CREATE:
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // использование файла подкачки
NULL, // защита по умолчанию
PAGE_READWRITE, // доступ к чтению/записи
0, // макс. размер объекта
BUF_SIZE, // размер буфера
"myFileMapping"); // имя отраженного в памяти объекта
if (hMapFile == NULL || hMapFile == INVALID_HANDLE_VALUE)
{
MessageBox(hWnd,
"Не может создать отраженный в памяти объект (%d).\n",
"Map", MB_OK);
return 0;
}
lpD= (D*) MapViewOfFile(hMapFile, // дескриптор отраж. в памяти объекта
FILE_MAP_ALL_ACCESS, // разрешение чтения/записи
0, 0, BUF_SIZE);
if (lpD == NULL)
{
MessageBox(hWnd,
"Представление проецированного файла не возможно (%d).\n",
"Map",MB_OK);
return 0;
}
hServerMutex = CreateMutexA(NULL, true, nameMutex);
if (hServerMutex == NULL) MessageBox(hWnd, "Error mutex", "Map",MB_OK);
// Создаем событиe с автосбросом, со сброшенным начальным состоянием
hEventVvod = CreateEvent(NULL, FALSE, TRUE, nameEvent);
hwndEdit = CreateWindow(TEXT("EDIT"), NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
10, 40, 500, 400, hWnd, NULL, hInst, NULL);
// Создаем поток
hThreads[0] = (HANDLE)_beginthreadex(NULL, 0, &VvodThreadFunc, 0, 0,&uThreadIDs[0]);
ReleaseMutex(hServerMutex);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
CloseHandle(hThreads[0]);
UnmapViewOfFile(lpD);
CloseHandle(hMapFile);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Приложение Г
Пример задания основных функций приложения-клиента с отображением файла на память
#include "stdafx.h"
#include "MapClient1.h"
#include <stdio.h>
#define MAX_LOADSTRING 100
#define BUF_SIZE 1024
HANDLE hMapFile;
struct D{
TCHAR Buf[1024];
};
D* lpD;
bool Podkluchen=false;
HINSTANCE hInst;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
LPCSTR nameMutex = "Global\\MapMutex";
LPTSTR nameEvent = L"Global\\MapEvent";
HANDLE hServerMutex; // дескриптор мьютекса на доступ к буферу памяти
HANDLE hEventVvod; // дескриптор события «Данные готовы»
//----------------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case ID_32773: //пункт меню «Подключиться»
if(Podkluchen) return 0;
hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // доступ к чтению/записи
FALSE, // имя не наследуется
"myFileMapping"); // имя "проецируемого " объекта
if (hMapFile == NULL)
{
MessageBox(hWnd,
"Невозможно открыть объект проекция файла",
"Клиент",MB_OK);
Podkluchen=false;
return 0;
}
lpD= (D*) MapViewOfFile(hMapFile, // дескриптор "проец." объекта
FILE_MAP_ALL_ACCESS, // разрешение чтения/записи
0, 0, BUF_SIZE);
if (lpD == NULL)
{
MessageBox(hWnd,
"Представление проецированного файла не возможно (%d).\n",
"Клиент",MB_OK);
Podkluchen=false;
return 0;
}
hServerMutex = CreateMutexA(NULL, true, nameMutex);
if (hServerMutex == NULL) MessageBox(hWnd, "Error mutex",
"Map",MB_OK);
// Откр. событиe с автосбросом, со сброшенным начальным состоянием
hEventVvod = OpenEvent(EVENT_ALL_ACCESS, FALSE, nameEvent);
Podkluchen=true;
break;
case ID_32772://пункт меню «послать сообщение»
if(Podkluchen)
{
FillMemory(lpD->Buf,1024,0); //очистка буфера
D.Buf = "Клиент. Сообщение";
SetEvent(hEventVvod);
ReleaseMutex(hServerMutex);
}else
MessageBox(hWnd,
"Надо подключиться к серверу\n", "Клиент1", MB_OK);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
UnmapViewOfFile(lpD);
CloseHandle(hMapFile);
ReleaseMutex(hServerMutex);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Приложение Д
Пример задания основных функций приложения-сервера с использованием почтового ящика
#include <stdio.h>
#define MAX_LOADSTRING 100
#define IDT_TIMER1 37000
// Global Variables:
HINSTANCE hInst;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
static HWND hwndEdit;
//----------------------------------
HANDLE Mail;
int flag = 0;
UINT idTimer;
BOOL Code; // Код возврата из функций
DWORD Msg; // Размер сообщения.
DWORD Number; // Количество сообщений в канале Mailslot
char szBuf[512];
char temp[10];
LPSTR MailslotName = "\\\\.\\mailslot\\$Box_1$";
DWORD cbRead; // Количество байт данных, принятых через канал
TCHAR mess[2048];
TCHAR* m_mess = mess;
//--------------------------------------------------------------------------------------------
void Create (LPSTR NameMailslot)
{
sprintf(m_mess, "Mailslot \r\n");
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
// Создаем канал Mailslot, имеющий имя NameMailslot, в результате в Mail сохран.хэндл на созданный канал
Mail = CreateMailslot(NameMailslot, 0, MAILSLOT_WAIT_FOREVER, NULL);
// Если возникла ошибка, выводим ее код и выходим из функции
if(Mail == INVALID_HANDLE_VALUE)
{
sprintf(m_mess, "%s \r\n Почтовый сервер. Error: %d \r\n ",m_mess,GetLastError());
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
return;
}
// Выводим сообщение о создании канала и обновляем данные
sprintf(m_mess, "%s\r\nСервер OK\r\n",m_mess);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
//Устанавливаем флаг успешного создания канала
flag=1;
return;
}
//--------------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_CREATE:
hwndEdit = CreateWindow(// Создаем доч.окно для вывода данных от процессов
TEXT("EDIT"), NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_READONLY | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
0, 0, 400, 200, hWnd, NULL, hInst, NULL);
break;
case WM_TIMER:
//Создаем мэйлслот, если это первый вызов функции
if(flag!=1)Create(MailslotName);
// Определяем состояние канала Mailslot
Code = GetMailslotInfo(Mail, NULL, &Msg, &Number, NULL);
if(!Code)
{
sprintf(m_mess, "%s \r\n Почтовый сервер. Error: %d \r\n", m_mess, GetLastError());
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
return 0;
}
// Если в канале есть Mailslot сообщения, читаем его и выводим
if(Number!= 0)
{
if(ReadFile(Mail, szBuf, 512, &cbRead, NULL))
{
//Выводим принятую строку
sprintf(m_mess, "%s \r\n Сообщение: \r\n %s \r\n ",m_mess,szBuf);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
}
else
{
sprintf(m_mess, "%s \r\n Чтение почты: Error %d \r\n ", m_mess, GetLastError());
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
return 0;
}
}
return 0;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case ID_32771: //Пуск сервера
if(flag ==0)
{
idTimer = SetTimer(hWnd,IDT_TIMER1, 1000, NULL);
FillMemory(m_mess,2048,0);
}
break;
case ID_32772:
sprintf(m_mess, "%s\r\nСтоп сервер OK\r\n",m_mess);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
flag=0;
KillTimer(hWnd,IDT_TIMER1);
CloseHandle(Mail);
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
if(flag!=0)
{
KillTimer(hWnd,IDT_TIMER1);
CloseHandle(Mail);
}
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Приложение Е
Пример задания основных функций приложения-клиента с использованием почтового ящика
#include <stdio.h>
#define MAX_LOADSTRING 100
//----------------------------------
HANDLE Mail;
int flag = 0;
UINT idTimer;
BOOL Code; // Код возврата из функций
DWORD Msg; // Размер сообщения.
DWORD Number; // Количество сообщений в канале Mailslot
char szBuf[512];
char temp[10];
LPSTR ServerName = "\\\\.\\mailslot\\$Box_1$";
DWORD cbRead; // Количество байт данных, принятых через канал
TCHAR mess[2048];
TCHAR* m_mess = mess;
//------------------------------------------------------------------------------------------------------
void Connect()
{
//Подключаемся к почтовому ящику
Mail = CreateFile(ServerName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
// Если возникла ошибка, выводим ее код и выходим из функции
if(Mail == INVALID_HANDLE_VALUE)
{
sprintf(m_mess, "CreateMailslot Error: %d \r\n", GetLastError());
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
return;
}
flag=1;
return;
}
//----------------------------------------------------------------------------------------------
void Send(HWND hWnd)
{
// Определение длины текста в поле редактирования
DWORD cbWritten = SendMessage(hwndEdit,WM_GETTEXTLENGTH,0,0);
if(flag!=1)
{
MessageBox(hWnd, "Сначала соединяемся...","MailClient 1",MB_OK);
Connect (); //Вызываем функцию подключения
};
//Читаем из поля редактирования набранную строку
SendMessage(hwndEdit, WM_GETTEXT, (WPARAM) cbWritten, (LPARAM) szBuf);
//Отсылаем введенную строку на сервер
WriteFile(Mail, szBuf, strlen(szBuf) + 1,&cbWritten, NULL);
return;
}
//----------------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{ int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_CREATE:
hwndEdit = CreateWindow(// Создаем доч.окно для вывода данных от процессов
TEXT("EDIT"), TEXT("Клиент. Сообщение\r\n"),
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
20, 10, 400, 200, hWnd, NULL, hInst, NULL);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Анализ выбранного пункта меню---------------:
switch (wmId)
{
case IDM_32771: //Пункт меню «Соединить»
Connect();
break;
case IDM_37772: //Пункт меню «Передать»
Send(hWnd);
break;
case ID_32776: //Пункт меню «Подготовить данные»
sprintf(m_mess, "Данные от клиента %d \r\n", vers);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
CloseHandle(Mail);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Приложение Ж
Пример задания основных функций приложения-сервера с обменом данными по именованному каналу с приложениями клиентами
#include "stdafx.h"
#include "PipeServer.h"
#include <process.h>
#include <stdio.h>
#define MAX_LOADSTRING 100
BOOL fConnected[2]={false,false}; //Флаги наличия соединения с каждым клиентом
BOOL stopwork = false; //флаг окончания работы параллельных потоков
HANDLE hNamedPipe[2]; //дескрипторы именованных каналов
LPSTR lpszPipeName = "\\\\.\\pipe\\my_pipe"; //общее имя для всех каналов
char szBuf[512]; //буфер данных
DWORD cbRead; //для хранения к-ва данных
int flag = 0;
static HWND hwndEdit; //поле для отображения или ввода текстовых сообщений
TCHAR mess[2048]; //буфер данных
TCHAR* m_mess = mess; //ссылка на буфер данных
int NP=-1; //К-во открытых каналов
unsigned uThreadIDs[2]; //идентификаторы запущенных потоков
HANDLE hThreads[2]; //дескрипторы запущенных потоков
//-------------------функция потока------------------------------------------------------------
unsigned __stdcall PipeThreadFunc(void * arg) // Поток, создающий именованный канал
{
if(stopwork){_endthreadex(0);return 0;} //если установлен флаг, останавливаем работу потока
DWORD err=0; //значение ошибки
DWORD nom = GetCurrentThreadId(); //получить идентификатор тек. потока
//установка индекса потока, с кот. будет выполняться работа
int j=0;
if(uThreadIDs[0]==nom)j=0;
if(uThreadIDs[1]==nom)j=1;
if(fConnected[j])goto read_mes; //проверка наличия связи с каналом
//если нет соединения, то создать именованный канал
hNamedPipe[j]=CreateNamedPipe(lpszPipeName, //имя канала
PIPE_ACCESS_DUPLEX, //дуплексная связь
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, //устан. режимов: чтение из канала,
//ожидание, неограниченное к-во экз. канала
512, 512, //размер буфера ввода и вывода канала
5000, //время ожидания связи = 5 сек
NULL); // атрибуты защиты – по умолчанию
if(hNamedPipe[j]==INVALID_HANDLE_VALUE)
{ //если ошибка:
err=GetLastError();
sprintf(m_mess, "%s \r\n Канал не создан. Error: %d \r\n ",m_mess,err);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
_endthreadex(0);
return err;
}
//иначе – сообщение об успешном создании канала-----------
sprintf(m_mess, "%s \r\n Канал № %d. Жду... \r\n ",m_mess,j+1);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
//установить флаг наличия связи с каналом--------------------
fConnected[j] = ConnectNamedPipe(hNamedPipe[j], NULL);
if(!fConnected[j])
{
err=GetLastError();
CloseHandle(hNamedPipe[j]);
sprintf(m_mess, "%s \r\n Соединения нет. Error: %d \r\n ",m_mess,err);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
_endthreadex(0);
return err;
}
read_mes: //основной цикл потока================================
while(!stopwork) //пока нет указания завершить работу
{
if(ReadFile(hNamedPipe[j], szBuf, 512, &cbRead, NULL))
{ //если принято сообщение
sprintf(m_mess, "%s \r\n Канал № %d. Принято байт = %d;\r\n %s \r\n ",
m_mess, j+1, cbRead, szBuf);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
}
else
{ //сообщить об ошибке
sprintf(m_mess, "%s \r\n Канал № %d.Чтение данных. Error: %d \r\n ",
m_mess, j+1, err);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
}
}
CloseHandle(hNamedPipe[j]);
_endthreadex(0);
return 0;
};
//-------------------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
DWORD nowait = PIPE_NOWAIT;
switch (message)
{
case WM_CREATE:
hwndEdit = CreateWindow(// Создаем доч.окно для вывода данных от процессов
TEXT("EDIT"), TEXT("Клиент. Сообщение\r\n"),
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
20, 10, 400, 200, hWnd, NULL, hInst, NULL);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case ID_32771: //Пункт меню «Создать канал»
NP++; //нарастить к-во каналов
if(NP>1) //ограничиваем к-во каналов <=2
{
NP=1;
sprintf(m_mess, "%s \r\n Error. Кол-во каналов >2!!!\r\n ",m_mess);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
return 0;
}
//создаем и запускаем поток для в кот. будет создан канал и
// запущен цикл приема сообщений от канала
hThreads[NP] = (HANDLE)_beginthreadex(NULL, 0, &PipeThreadFunc, 0, 0,
&uThreadIDs[NP]);
sprintf(m_mess, "%s \r\n Добавлен канал № %d\r\n ",m_mess,NP+1);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
stopwork=true; //установить флаг завершения работы потоков
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
CloseHandle(hThreads[0]); //освободить память от дескрипторов
CloseHandle(hThreads[1]);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Приложение З
Пример задания основных функций приложения-клиента с обменом данными по именованному каналу с сервером
#include <stdio.h>
#define MAX_LOADSTRING 100
BOOL fConnected=false; //Флаг наличия соединения с сервером
HANDLE hNamedPipe; //дескриптор именованного канала
LPSTR lpszPipeName = "\\\\.\\pipe\\my_pipe"; //общее имя для всех каналов
char szBuf[256]; //буфер данных
DWORD cbWritten; //для хранения к-ва данных
static HWND hwndEdit; //поле для отображения или ввода текстовых сообщений
TCHAR mess[2048]; //буфер данных
TCHAR* m_mess = mess; //ссылка на буфер данных
// Global Variables:
HINSTANCE hInst;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
//----------------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
DWORD err=0;
switch (message)
{
case WM_CREATE:
hwndEdit = CreateWindow(// Создаем доч.окно для вывода данных от процессов
TEXT("EDIT"), TEXT("Клиент. Сообщение\r\n"),
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
20, 10, 400, 200, hWnd, NULL, hInst, NULL);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case ID_32771: //Пункт меню «Открыть канал»
if(fConnected)return 0;
hNamedPipe=CreateFile(lpszPipeName,
GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
if(hNamedPipe == INVALID_HANDLE_VALUE)
{
err=GetLastError();
sprintf(m_mess, "%s \r\n Канал не открыт. Error: %d \r\n ",m_mess,err);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
return 0;
}
sprintf(m_mess, "%s \r\n Канал открыт.\r\n ",m_mess);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
fConnected=true;
break;
case ID_32772: //Пункт меню «Послать данные»
if(!fConnected) //если нет соединения с каналом
{
sprintf(m_mess, "%s \r\n Канал не открыт. \r\n ",m_mess);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
return 0;
}
// Определить длину данных
cbWritten = SendMessage(hwndEdit, WM_GETTEXTLENGTH, 0, 0);
// прочитать данные в буфер
SendMessage(hwndEdit, WM_GETTEXT, (WPARAM) cbWritten, (LPARAM) szBuf);
//записать данные в канал--------------------------------------
if(WriteFile(hNamedPipe, szBuf, strlen(szBuf)+1, &cbWritten, NULL))
{
sprintf(m_mess, "\r\n Данные отосланы \r\n %s",szBuf);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
}
else
{
sprintf(m_mess, "%s \r\n Error: %d \r\n ",m_mess,err);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
}
break;
case ID_32773: //Пункт меню «Подготовить данные»
Task1(); //подпрограмма, кот. В соотв. с вариантом записывает
// данные в поле hwndEdit
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
CloseHandle(hNamedPipe); //закрыть дескриптор канала
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Приложение И
Распечатка программы сервера
// SocketServer.cpp
//
#include "stdafx.h"
#include "SocketServer.h"
#include <windows.h>
#include <windowsx.h>
#include <winsock.h>
#include <commctrl.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX_LOADSTRING 100
char szBuf[512];
DWORD cbWritten;
static HWND hwndEdit;
TCHAR mess[2048];
TCHAR* m_mess = mess;
#define SERV_PORT 5000 // Порт сервера
#define WSA_ACCEPT (WM_USER+0)
#define WSA_NETEVENT (WM_USER+1)
WSADATA wsaData; //сведения о конкр. реализации интерфейса Windows Sockets
WORD wVersionRequested = MAKEWORD(1, 1); //Номер требуемой версии Windows Sockets
int err=0;
SOCKET srv_socket=INVALID_SOCKET; // Сокет сервера
int ClientNum = -1; // Номер последнего клиента
SOCKET sock[2]; // Сокеты клиентов
SOCKADDR_IN sockaddr[2]; // Адреса клиентов
//=========================================
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
HWND hWindow;
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_SOCKETSERVER, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{ return FALSE; }
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SOCKETSERVER));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SOCKETSERVER));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_SOCKETSERVER);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 400, 300, NULL, NULL, hInstance, NULL);
if (!hWnd) return FALSE;
hWindow=hWnd;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
void ServerStart(HWND hWnd)
{
if(srv_socket!= INVALID_SOCKET)
{
MessageBox(hWnd, "Socket уже есть", "Info", MB_OK | MB_ICONINFORMATION);
return;
}
// создаем сокет сервера для работы с потоком данных
srv_socket = socket(AF_INET, SOCK_STREAM, 0);
if(srv_socket == INVALID_SOCKET)
{
MessageBox(hWnd, "Ошибка создания сокета!!!", "Error", MB_OK | MB_ICONERROR);
return;
}
// Устанавливаем адрес IP и номер порта
SOCKADDR_IN srv_address;
srv_address.sin_family = AF_INET;
srv_address.sin_port = htons(SERV_PORT);
srv_address.sin_addr.s_addr = INADDR_ANY; // исп. адрес по умолчанию (т.е. любой)
// Связываем адрес IP с сокетом
if(SOCKET_ERROR ==bind(srv_socket,(LPSOCKADDR) &srv_address, sizeof(srv_address)))
{
closesocket(srv_socket);
MessageBox(hWnd, "Ошибка связывания с портом", "Error", MB_OK | MB_ICONSTOP);
return;
}
// ожидаем установки связи
if(listen(srv_socket, 4) == SOCKET_ERROR)
{
closesocket(srv_socket);
MessageBox(hWnd, "Ошибка ожидания установки связи","Error", MB_OK);
return;
}
// при попытке соединения главное окно получит сообщение WSA_ACCEPT
int rc = WSAAsyncSelect(srv_socket, hWnd, WSA_ACCEPT, FD_ACCEPT);
if(rc)
{
closesocket(srv_socket);
MessageBox(hWnd, "WSAAsyncSelect error","Error", MB_OK);
return;
}
// Выводим сообщение о запуске сервера
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM) "Сервер запущен");
}
void ServerStop(HWND hWnd)
{
// отменяем приход сообщений в главную функцию окна при возникновении
// любых событий, связанных с системой Windows Sockets
WSAAsyncSelect(srv_socket, hWnd, 0, 0);
if(srv_socket!= INVALID_SOCKET) // если сокет был создан, закрываем его
{
closesocket(srv_socket);
srv_socket = INVALID_SOCKET;
}
// выводим сообщение об останове сервера
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM) "Сервер остановлен");
}
BOOL AcceptClient(int j) // присоединить клиента
{
int sockaddr_len = sizeof(sockaddr[j]);
sock[j]=accept(srv_socket,(LPSOCKADDR)&sockaddr[j],(int FAR*)&sockaddr_len);
if(sock[j]!= INVALID_SOCKET)
if(!WSAAsyncSelect(sock[j],hWindow,WSA_NETEVENT, FD_READ | FD_CLOSE))
return TRUE;
closesocket(sock[j]);
return FALSE;
}
void DisconnectClient(int j) // отключить клиента
{
WSAAsyncSelect(sock[j], hWindow, 0, 0);
closesocket(sock[j]);
}
void WndProc_OnWSAAccept(HWND hWnd, LPARAM lParam)
{
// при ошибке отменяем поступление сообщений в главное окно приложения
if(WSAGETSELECTERROR(lParam)) {
MessageBox(hWnd, "accept error", "Error", MB_OK);
WSAAsyncSelect(srv_socket, hWnd, 0, 0);
return;
}
if(ClientNum == 1) {
MessageBox(hWnd,"число клиентов >2\r\n", "Соединение недопустимо!", MB_OK);
return;
}
ClientNum++;
if(!AcceptClient(ClientNum)) {
MessageBox(hWnd, "Ошибка соед с клиентом", "Error", MB_OK);
return;
}
// добавляем клиента
sprintf(szBuf, "Добавлен клиент %i\r\nАдрес: IP=%s Port=%u\r\n \0", ClientNum+1,
inet_ntoa(sockaddr[ClientNum].sin_addr), htons(sockaddr[ClientNum].sin_port));
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)szBuf);
}
void WndProc_OnWSANetEvent(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
char szTemp[256], szMess[256];
int Number;
// узнаем от какого клиента пришло сообщение, => Number
if(sock[0]==(SOCKET) wParam) Number=0;
else if(sock[1]==(SOCKET) wParam) Number=1;
// если на сокете выполняется передача данных, принимаем и отображаем их
if(WSAGETSELECTEVENT(lParam) == FD_READ)
{
int rc = recv((SOCKET) wParam, szTemp, 256, 0);
if(rc){
szTemp[rc]='\0';
sprintf(m_mess, "%s \r\n Данные от Клиента %i:\r\n%s", m_mess, Number+1,szTemp);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
}
}
// если соединение завершено, выводим сообщение об этом
if(WSAGETSELECTEVENT(lParam) == FD_CLOSE)
{
WSAAsyncSelect(sock[Number], hWindow, 0, 0);
closesocket(sock[Number]);
sprintf(szTemp, "Клиент %i завершил работу", Number+1);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)szTemp);
}
}
void SendToClient(int j)
{
if(j>ClientNum) return;
cbWritten = SendMessage(hwndEdit,WM_GETTEXTLENGTH,0,0);
SendMessage(hwndEdit, WM_GETTEXT, (WPARAM) cbWritten, (LPARAM) szBuf);
szBuf[cbWritten]='\0';
if(send(sock[j],szBuf,lstrlen(szBuf),0)!= SOCKET_ERROR)
{
sprintf(szBuf, "Данные отосланы клиенту %d\r\n %s",j+1,szBuf);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)szBuf);
}
else
SendMessage(hwndEdit,WM_SETTEXT, 0, (LPARAM)"Ошибка отправки сообщения \r\n");
}
void ClientOff(HWND hWnd, int j)
{
if(j>ClientNum) return;
sprintf(szBuf, "Отключить Клиента %i?", j+1);
if(IDYES == MessageBox(hWnd, szBuf, "Question", MB_YESNO | MB_ICONQUESTION))
DisconnectClient(j);
ClientNum--;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_CREATE:
hwndEdit = CreateWindow(// Создаем доч.окно для вывода данных от процессов
TEXT("EDIT"), NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
0, 0, 400, 200, hWnd, NULL, hInst, NULL);
//===========================================================
err = WSAStartup(wVersionRequested, &wsaData);
if(err) {
MessageBox(hWnd, "WSAStartup Error","ERROR", MB_OK | MB_ICONSTOP);
return FALSE;
}
sprintf(m_mess, "Используется %s \r\nСтатус: %s\r\n",
wsaData.szDescription, wsaData.szSystemStatus);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case ID_32771:
ServerStart(hWnd);
break;
case ID_32772:
ServerStop(hWnd);
break;
case ID_32773:
SendToClient(0);
break;
case ID_32774:
SendToClient(1);
break;
case ID_32775:
ClientOff(hWnd, 0);
break;
case ID_32776:
ClientOff(hWnd, 1);
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
WSACleanup();
PostQuitMessage(0);
break;
case WSA_ACCEPT:
WndProc_OnWSAAccept(hWnd, lParam);
break;
case WSA_NETEVENT:
WndProc_OnWSANetEvent(hWnd, wParam, lParam);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Приложение К
Распечатка программы клиента
// SocketClient1.cpp: Defines the entry point for the application.
#include "stdafx.h"
#include "SocketClient1.h"
#include <winsock.h>
#include <process.h>
#include <stdio.h>
#define MAX_LOADSTRING 100
char szBuf[512];
DWORD cbWritten;
int flag = 0;
static HWND hwndEdit;
TCHAR mess[2048];
TCHAR* m_mess = mess;
//=========================================
#define SERV_PORT 5000 // Порт сервера
#define WSA_NETEVENT (WM_USER+1)
WSADATA wsaData; //сведения о конкретной реализации интерфейса Windows Sockets
WORD wVersionRequested = MAKEWORD(1, 1); //Номер требуемой версии Windows Sockets
int err=0;
SOCKET cln_socket=INVALID_SOCKET; // Сокет сервера
static PHOSTENT phe;
SOCKADDR_IN dest_sin; // Адрес сервера
char szHostName[128] = "localhost"; //имя хоста
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_SOCKETCLIENT1, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SOCKETCLIENT1));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SOCKETCLIENT1));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_SOCKETCLIENT1);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 400, 250, NULL, NULL, hInstance, NULL);
if (!hWnd) return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
void Task1()
{ //Подготовка информации в соответствии з заданием на курсовую работу
sprintf(m_mess, "%s Здесь готовятся данные %d \r\n",m_mess, vers);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)m_mess);
}
BOOL SetConnection(HWND hWnd)
{
cln_socket = socket(AF_INET, SOCK_STREAM, 0); // создаем сокет
if (cln_socket == INVALID_SOCKET)
{
MessageBox(hWnd, "Socket error", "Error", MB_OK | MB_ICONSTOP);
return FALSE;
}
phe = gethostbyname(szHostName); // Определяем адрес узла
if(phe == NULL)
{
closesocket(cln_socket);
MessageBox(hWnd, "Адрес хоста не определен", "Error", MB_OK | MB_ICONSTOP);
return FALSE;
}
dest_sin.sin_family = AF_INET; // Задаем тип адреса
dest_sin.sin_port = htons(SERV_PORT); // Устанавливаем номер порта
memcpy((char FAR*) &(dest_sin.sin_addr), phe->h_addr, phe->h_length);// Копируем адрес узла
// Устанавливаем соединение<