Автор работы: Пользователь скрыл имя, 17 Июня 2013 в 00:52, курсовая работа
Активно внедряя автоматизацию в сферу рассылки и получения новостей, руководство Министерства информации четко определило главную цель: повышение качества и уровня доставки информации, создание оптимальных условий для получения информации к пользователю. Успех в этой работе во многом зависит от того, насколько технологически грамотно весь этот сложный программно-технический комплекс будет использован для главной цели его создания – эффективной рассылки и получения новостей посредством технологии клиент – сервер на основе WINDOWS SOCKETS используя API функции.
Целью данной работы является составление программного обеспечения для рассылки и получения.
Введение………………………………………….……………………………………41 Обзор состояния вопроса ель и задачи работы…………….……………………...5
2 Постановка задачи………………………………………………….………..……...7
3 Моделирование ПО……………………………….………………………………...8
3.1 Архитектура ПО…………………………….…………………………………..8
3.2 Интерфейс пользователя………………………………………………………11
3.3 Описание основных функциональных модулей……………………………..14
3.4 Структура классов и объектов………………………………………………...24
4 Реализация ПО……………………………………………………………………..28
5 Руководство пользователя………………………………...………………………29
Заключение…………………………...………………………………………………34Список используемой литературы…………………………………………...……..35
if(bmp_border != NULL)
DeleteObject(bmp_border);
bmp_border = NULL;
if(dc_border != NULL)
DeleteDC(dc_border);
dc_border = NULL;
if(bmp_border2 != NULL)
DeleteObject(bmp_border2);
bmp_border2 = NULL;
if(dc_border2 != NULL)
DeleteDC(dc_border2);
dc_border2 = NULL;
if(brush_back != NULL)
DeleteObject(brush_back);
brush_back = NULL;
if(brush_back2 != NULL)
DeleteObject(brush_back2);
brush_back2 = NULL;
if(bitmap != NULL)
DeleteObject(bitmap);
bitmap = NULL;
if(bdc != NULL)
DeleteDC(bdc);
bdc = NULL;
if(cwnd != NULL)
DestroyWindow(cwnd);
cwnd = NULL;
if(msgs.size() > 0u)
msgs.clear();
size_txt.cx = size_txt.cy = font_cy = 0L;
}
// Приватный обработчик передаём
глобальному обработчику
LRESULT CALLBACK xEditOutput::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
xEditOutput* obj = NULL;
if(msg == WM_CREATE) {
LPCREATESTRUCTA ptr = (LPCREATESTRUCTA)lParam;
SetLong(hwnd, GWL_USERDATA, (DWORD)ptr->lpCreateParams);
((xEditOutput*)ptr->
}
if((obj = reinterpret_cast<xEditOutput*>
return obj->ControlProc(msg, wParam, lParam);
return DefWindowProcA(hwnd, msg, wParam, lParam);
}
void xEditOutput::Clear(void) {
if(msgs.size() > 0u) {
EnterCriticalSection(§ion)
msgs.clear();
size_txt.cy = 0L;
this->update();
InvalidateRect(cwnd, NULL, TRUE);
LeaveCriticalSection(§ion)
}
}
SetRect(&rect, 0, 0, size_txt.cx, font_cy);
int height = DrawTextA(bdc, msg, lstrlenA(msg), &rect, DT_WORDBREAK | DT_LEFT | DT_CALCRECT);
EnterCriticalSection(§ion)
msgs.push_back(xMsg(user, msg, buf, rect.bottom + font_cy, my));
size_txt.cy += (rect.bottom + font_cy);
this->update(false);
InvalidateRect(cwnd, NULL, TRUE);
LeaveCriticalSection(§ion)
}
void xEditOutput::update(bool reset) {
SCROLLINFO sinfo;
COLORREF col1, col2, col3;
HBRUSH brush;
int y = 0;
RECT rect;
RECT rc;
y -= GetScrollPos(cwnd, SB_VERT);
for(size_t i = 0u; i < msgs.size(); i++) {
if(y > -100) {
if(msgs[i].my) {
col1 = RGB(47, 47, 47);
col2 = RGB(111, 111, 111);
col3 = RGB(100, 100, 100);
brush = brush_back2;
BitBlt(bdc, 2, y, size_txt.cx, font_cy, dc_border2, 0, 0, SRCCOPY);
} else {
col1 = RGB(0, 99, 99);
col2 = RGB(60, 175, 175);
col3 = RGB(0, 0, 0);
brush = brush_back;
BitBlt(bdc, 2, y, size_txt.cx, font_cy, dc_border, 0, 0, SRCCOPY);
}
SetTextColor(bdc, col2);
TextOutA(bdc, size_txt.cx - 43, y, msgs[i].date, msgs[i].len_date);
SetTextColor(bdc, col3);
InflateRect(&rect, -2, 0);
DrawTextA(bdc, msgs[i].msg, msgs[i].len_msg, &rect, DT_WORDBREAK | DT_LEFT);
}
y += msgs[i].height;
if(y > rc.bottom)
break;
}
3.4 Структура классов и объектов
Опишем структуру классов и объектов
// класс-объект реализующий TCP-
class xTCPClient {
typedef void (OnRead)(const CHAR* buf, int size);
typedef void (OnError)(int code);
private:
SOCKET client;
HANDLE thread;
OnRead* reader;
OnError* error;
volatile BOOL loop;
public:
xTCPClient(void) {
thread = NULL;
client = 0u;
loop = FALSE;
reader = NULL;
error = NULL;
}
~xTCPClient() {
this->Close();
}
// Метод создаёт сокет и
public:
BOOL Create(const CHAR* host_ip, USHORT port, int& err, OnRead* on_read = NULL, OnError* on_error = NULL) {
hostent* host = NULL;
// создаём сокет
client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(client == INVALID_SOCKET) { // WSAGetLastError
err = WSAGetLastError();
return FALSE;
}
sockaddr_in addr;
ZeroMemory(&addr, sizeof(sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(host_ip);
if(addr.sin_addr.s_addr == INADDR_NONE) {
if((host = gethostbyname(host_ip)) == NULL) {
err = WSAGetLastError();
return FALSE;
}
CopyMemory(&addr.sin_addr, host->h_addr_list[0], host->h_length);
}
int size = sizeof(int);
int bufsize = 0;
// проверяем размер приёмного-буфера tcp
if(getsockopt(client, SOL_SOCKET, SO_RCVBUF, (char*)&bufsize, &size) != SOCKET_ERROR) {
if(bufsize < BUFSIZE) {
// если меньше указанного
bufsize = BUFSIZE;
setsockopt(client, SOL_SOCKET, SO_RCVBUF, (const char*)&bufsize, sizeof(int));
}
}
// также проверяем посылаемого-буфера tcp
if(getsockopt(client, SOL_SOCKET, SO_SNDBUF, (char*)&bufsize, &size) != SOCKET_ERROR) {
if(bufsize < BUFSIZE) {
bufsize = BUFSIZE;
setsockopt(client, SOL_SOCKET, SO_SNDBUF, (const char*)&bufsize, sizeof(int));
}
}
// подключаемся к серверу
int res = connect(client, (const sockaddr*)&addr, sizeof(addr));
if(res == SOCKET_ERROR) {
err = WSAGetLastError();
return FALSE;
}
thread = CreateThread(NULL, 0u, (LPTHREAD_START_ROUTINE)
if(thread == NULL) {
err = GetLastError();
return FALSE;
}
loop = TRUE;
reader = on_read;
error = on_error;
ResumeThread(thread);
return TRUE;
}
// Метод для рассылки новостей
bool Send(const CHAR* buf, int& err) {
if(send(client, buf, min(lstrlenA(buf), BUFSIZE - 1), 0) == SOCKET_ERROR) {
err = WSAGetLastError();
return false;
}
return true;
}
// Метод закрывает сокет и поток
void Close(void) {
loop = FALSE;
if(thread != NULL) {
if(WaitForSingleObject(thread, 1000u) == WAIT_TIMEOUT)
TerminateThread(thread, 0u);
CloseHandle(thread);
}
thread = NULL;
if(client != 0u)
closesocket(client);
client = 0u;
}
// Функция ожидания
void Wait(void) {
if(thread != NULL)
WaitForSingleObject(thread, INFINITE);
}
static bool Init(void) {
WSADATA data;
ZeroMemory(&data, sizeof(WSADATA));
if(WSAStartup(MAKEWORD(2, 2), &data) != 0)
return false;
return true;
}
static void Free(void) {
WSACleanup();
}
private:
// Приватный статический метод потока, для принятий данных от сервера
static DWORD WINAPI ThreadReader(LPVOID param) {
xTCPClient* ptr = reinterpret_cast<xTCPClient*>(
int result;
CHAR buf[BUFSIZE];
while(ptr->loop) {
result = recv(ptr->client, buf, BUFSIZE - 1, 0);
if(result > 0) {
buf[result] = '\0';
if(ptr->reader != NULL)
(*ptr->reader)(buf, result);
} else {
if(ptr->error != NULL)
(*ptr->error)(WSAGetLastError(
if(result == SOCKET_ERROR)
break;
}
}
return 0u;
}
};
//Класс описывающий параметры рабочей области создаваемого приложения (размер текста, фон, размер окна и др.)
class xEditOutput {
private:
HWND cparent;
HWND cwnd;
HINSTANCE cInstance;
UINT cid;
HFONT font;
HBITMAP bitmap;
HDC bdc;
SIZE size_txt;
long font_cy;
HBITMAP bmp_border;
HDC dc_border;
HBITMAP bmp_border2;
HDC dc_border2;
HBRUSH brush_back;
HBRUSH brush_back2;
CRITICAL_SECTION section;
//Метод, описывающий параметры констант
std::vector<xMsg> msgs;
public:
xEditOutput(HINSTANCE hInstance);
~xEditOutput();
public:
BOOL Create(HWND parent, int x, int y, int width, int height, UINT ID);
void Destroy(void);
void Add(const CHAR* user, const CHAR* msg, bool my = false);
void Clear(void);
size_t GetSize(void) const {
return msgs.size();
}
4 РЕАЛИЗАЦИЯ ПО
Реализация создаваемого программного продукта осуществляется для систем, в которых ведется рассылка новостей. Подробное описание работы с программой приведено в разделе 5. Для функционирования программы необходим персональный компьютер определенной конфигурации. Программа может работать в операционных системах Windows 3.1./95/98/Me/NT/2000/XP с поддержкой технологии TCP/IP.
Минимальный размер места на винчестере для корректной работы с программой – 99500Кб.
Перед началом установки ПО, необходимо произвести пинг рабочей сети, если сбоев не обнаружено, можно устанавливать сервер (консольное приложения). В данной консоли будет вестись передача приема отправки сообщений, количество переданных байт и др.
После того, как сервер запущен, в нем выставляем необходимые параметры, с которыми будет работать та сеть, в которую будем осуществлять рассылку новостей.
Далее следует запустить приложение для передачи (приема) рассылки новостей. В этом приложении прописываем данные сети, с которыми работаем предприятие (фирма). Подлее подробная работа с ПО рассмотрена в разделе 5.
Стоит отметить, что реализацию данного ПО можно осуществлять для любого предприятия, компании (фирмы). Так как система не требует больших вложений, имеет экономический эффект и демонстрирует быструю отправку и прием сообщений (при условии, что вы используете не очень старую сетевую плату) можно ее применять на практике в любой сфере деятельности, где требуется постоянно получать новости, данные, необходимую информацию.
5 РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ
Начало работы происходит с запуска серверной части ПО (рисунок 5.1).
Рисунок 5.1 – Запуск серверной части ПО
Следующим шагом является ввод цифровых значений порта сервера. Введем произвольное значение для примера. Значение будет равным «7777» (рисунок 5.2).
Рисунок 5.2 – Ввод значений порта для сервера рассылки новостей
После проделанных манипуляций нажимаем клавишу «Enter». Если все сделано правильно появится следующая надпись (рисунок 5.3).
Рисунок 5.3 – Запуск сервера рассылок новостей
Надпись зеленым цветом «Для остановки сервера любая клавиша» означает в нашем случае лишь одно – сервер запущен и работает успешно.
Далее, для дальнейшей работы необходимо запустить клиентскую часть созданного ПО для рассылки и приема новостей. Двойным щелчком мыши жмем по файлу «клиент.exe», после чего на экране появится следующая форма (рисунок 5.4).
Рисунок 5.4 – Запуск клиентской части ПО
Как видно на рисунке 5.4 в окошке клиентской части программы имеется три строки для ввода информации. Причем одна из них имеет обязательно числовое значение (Порт).
По умолчанию в строке «Введите IP-адрес» стоит «localhost», оставляем его без изменений, в строке «Порт» прописываем наши «7777» (ранее, мы их вводили в серверную часть программы), в строке «Ваше имя» впишем слово «Юзер».
Нажимаем кнопку «Соединение». Если все сделано правильно, то должно появиться следующее (рисунок 5.5):
Рисунок 5.5 – Запуск клиентской части для непосредственной отправки новостей пользователям
Как видно на рисунке 5.5 данное окошко клиентской части имеет два раздела. Первое показывает те новости, которые рассылает пользователь. Второе, находится ниже, служит для написания новостей. Кнопка «Отправить» соответственно рассылает новости всем зарегистрированным пользователям.
Попытаемся сделать рассылку (рисунок 5.6).
Рисунок 5.6 – Пример рассылки новостей пользователям
Как видно из рисунка 5.6 мы сделали успешно нашу первую рассылку. Только вот ее никто пока не может прочитать. Запустим клиентскую часть для приема рассылок новостей пользователями. Имя пользователю присвоим «Читатель». Все остальные параметры схожи с предыдущими (рисунок 5.7).
Рисунок 5.7 – Вход пользователя для чтения рассылки новостей
Жмем кнопку «Соединение» после чего должно произойти следующее (рисунок 5.8):
Рисунок 5.8 – ПО для просмотра (приема) рассылки новостей
Пользователь «Читатель» удачно вошел в свою клиентскую часть для приема рассылки новостей. Для того, чтобы в окошке «Последние Новости» появилась рассылка, пользователь «Юзер», которого мы создали для примера, должен снова сделать данную рассылку (рисунок 5.9).
Рисунок 5.9 – ПО для просмотра (приема) рассылки новостей с заполненными атрибутами
Следует отметить, что в клиентской части, пользователь видит от кого данная рассылка, время рассылки, что весьма хорошо сказывается на функциональность данной разработки.
ЗАКЛЮЧЕНИЕ
При выполнении курсового проекта
были пройдены все этапы разработки
специализированного
В процессе выполнения проекта была реализована следующая работа:
1. Освоение принципов разработки алгоритмов решения задач на ПЭВМ;
2. Овладение навыками программирования задач на языке С++, освоение практических приемов записи базовых конструкций языка и программирования линейных, разветвляющихся, циклических вычислительных процессов, отладки и выполнения программ с использованием интегрированной среды разработки Visual Studio. Net;
3. Ознакомление с различными сферами применения ПЭВМ в современном обществе, приобретение важных навыков работы с персональным компьютером.
Существует возможность
Исполняемый модуль и исходные коды на языке C++ прилагаются на дискете.