Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
УО «Полоцкий государственный университет»
Кафедра вычислительных систем и сетей
к курсовому проекту
по дисциплине «Системное программное обепечение»
Тема: «Проектирование сетевого приложения - чат»
Исполнитель: Шенделев С.В.
студент 4 курса группы 08-ВС
Руководитель: Травкин О.Н
Полоцк 2011г.
Изм.
Лист
№ докум.
Подпись
Дата
Лист
2
Курсовой проект
Разраб.
Шенделев С.В.
Провер.
Травкин О.Н.
Реценз.
Н. Контр.
Утверд.
Разработка сетевого чата
Лит.
Листов
УО «ПГУ», гр. 08ВС
Содержание
3
4
6
19
23
24
25
27
29
Введение………………………………………………………………………...
1. Анализ исходных данных……………………………………………………
2. Проектирование программного комплекса…………………………………
3. Разработка и тестирование программного комплекса……………………..
Заключение…………………………………………………………….………
Список использованной литературы………………………………………….
Приложения А. Диаграмма классов……………………………………….…
Приложение Б. Диаграмма прецедентов…………………………………..…...
Приложение В. Диаграмма компонентов………………………………………………….…..
Приложение Г. Диаграмма взаимодействий……………………………………………….…31
Приложение Д. Диаграмма развёртывания………………………………………………….…33
Приложение Е. Протокол тестирования.………………………………………………….…….35
Приложение Ж. Руководство пользователя……………………………………..………….…37
Приложение З. Техническое задание………………………………………………….….………39
Изм.
Лист
№ докум.
Подпись
Дата
Лист
3
КУРСОВОЙ ПРОЕКТ
Введение
Цель курсового проекта: создание программы обмена текстовыми сообщениями через локальную сеть.
Программа должна осуществлять передачу текстовых сообщений по сети. Архитектура программы должна включать в себя клиентскую и серверную часть. Чтобы начать обмен текстовыми сообщениями, на одном из компьютеров локальной сети должна быть запущена копия программы в серверном режиме. Для того, что бы программа знала, кому и куда передавать нужные сообщения необходимо использовать IP адрес и порт.
Перед передачей текстовых сообщений необходимо настроить обязательные параметры: вначале программы пользователю предлагают создать свой сервер либо быть клиентом (подключиться к уже созданному серверу в сети), далее необходимо ввести индивидуальное имя пользователя, IP- адрес и номер порта подключения. После выполнения настроек всех параметров программы в поле “окна текстовых сообщений” вводим нужную нам текстовую информацию и отправляем всем пользователем чата (отправка осуществляется по типу клиент0=>сервер=>клиент1 =>клиент2=>клиент n). Окно “чата сообщений” будет отображать всю переписку текстовыми сообщениями всех клиентов, находящихся на данном сервере. Весь архив сообщений можно узнать путём нажатия на кнопку “открыть логи”, где содержится история всей переписки пользователя. В данном архиве должна содержаться информация о имени получателя (отправителя) сообщений, непосредственно само сообщение и время и дата отправление (получения) сообщения.
Изм.
Лист
№ докум.
Подпись
Дата
Лист
4
КУРСОВОЙ ПРОЕКТ
При выполении данного курсового проекта будем использовать среду разработки Microsoft Visual Studio 2008 VС++.
Выбор данной среды разработки объясняется рядом приемуществ:
Изм.
Лист
№ докум.
Подпись
Дата
Лист
5
КУРСОВОЙ ПРОЕКТ
ПО, Visual Studio помогает создавать более удобные пользовательские интерфейсы, связывать приложения и бизнес-процессы и ускорять реализацию решений.
Изм.
Лист
№ докум.
Подпись
Дата
Лист
6
КУРСОВОЙ ПРОЕКТ
2. Проектирование программного комплекса
При создании программного комплекса, необходимо установить ключевые элементы управления программой. Данными элементами являются: кнопки создания сервера (если сервер не создан), подключения клиента к серверу, выход либо остановка чата, отправка введённого сообщения, отображения архива сообщений; так же области ввода имени (nick name) пользователя, ввод IP-адреса подключения, номера порта, окно ввода сообщений, окно отображения полученных сообщений.
На стороне сервера весь программный комплекс представляет собой:
На стороне клиента программный комплекс представлен следующими действиями:
Программный комплекс сокета представлен следующими действами:
Схема отправки сообщений представлена на рисунке 1.
Рисунок 1. Схема отправки сообщений
Изм.
Лист
№ докум.
Подпись
Дата
Лист
7
КУРСОВОЙ ПРОЕКТ
Изм.
Лист
№ докум.
Подпись
Дата
Лист
8
КУРСОВОЙ ПРОЕКТ
Разработанная программа содержит файлы:
ChatCppDlg.cpp ОСНОВНОЙ файл реализации функций, включающий класс диалогового окна.
Это главный файл проекта для VC C++. Проекты генерируется с использованием
мастера приложений. Он содержит информацию о версии Visual C++, информацию
о платформах, конфигурацию и особенность проекта.
ChatCpp.h
Основной включаемый файл приложения. В нем описан главный класс приложения
CChatCppApp, а также подключены другие включаемые файлы;
ChatCpp.cpp
Основной файл приложения. В нем определены методы главного класса CChatCppApp
приложения и глобальные объекты;
Sock.cpp класс сокетов;
ChatCpp.rc
Файл ресурсов. В этом файле описаны все ресурсы приложения.
Сами ресурсы могут быть записаны в каталоге RES, расположенном в главном каталоге проекта;
res\ChatCpp.ico
Файл иконки, который используется для прикладного окна;
res\ChatCpp.rc2
В этом файле определены ресурсы, которые нельзя редактировать с помощью
редактора ресурсов среды Visual C++.
/////////////////////////////////////////////////////////////////////////////
ChatCppDlg.h ключает информацию о структуре (имени чатующего, буфер сообщений, времени и дату получателя сообщения), устанавливает связь между диалоговым окном и программой;
/////////////////////////////////////////////////////////////////////////////
Другие стандартные файлы:
StdAfx.h
Включаются заголовочные файлы, которые редко меняются.Или вообще никогда не меняются для
данного проекта (те же stdio.h или windows.h). Чтобы откомпилировать один раз и забыть.
Сопутствующий файл - stdafx.cpp - обычно содержит только #include "stdafx.h".
Он, собственно, и компилируется.
Resource.h
Стандартный файл заголовка. Visual C++ читает и корректирует этот файл.
ChatCpp.manifest
Файл описывает тип платформы, версию, тип проекта и т.д.
/////////////////////////////////////////////////////////////////////////////
ReadMe.txt
Описание всех заголовочных файлов, файлов исходного кода, а так-же файлов ресурсов.
///////////////////////////////////////////////////////////////////////
Изм.
Лист
№ докум.
Подпись
Дата
Лист
9
КУРСОВОЙ ПРОЕКТ
Листинг основного файла реализации:
// файл реализации
#include <stdio.h>
#include <stdlib.h>
#include "stdafx.h"
#include "ChatCppDlg.h"
#include ".\chatcppdlg.h"
// CAboutDlg => класс диалогового окна
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// связь с ABOUTBOX через индентификатор IDD
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); //функция обмена данными
// реализация
protected:
DECLARE_MESSAGE_MAP() // таблица откликов
public:
afx_msg void OnBnClickedOk();
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
ON_BN_CLICKED(IDOK, &CAboutDlg::OnBnClickedOk)
END_MESSAGE_MAP()
// CChatCppDlg реализация
CChatCppDlg::CChatCppDlg(CWnd* pParent /*=NULL*/)
: CDialog(CChatCppDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CChatCppDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_RADIO_SERVER, m_ButtonStartServer); // Связывет объект сервера с контролом Server
DDX_Control(pDX, IDC_RADIO_CLIENT, m_ButtonStartClient);
DDX_Control(pDX, IDC_EDIT_NAME, m_wndName);
DDX_Control(pDX, IDC_EDIT_IP, m_wndIPAddress);
DDX_Control(pDX, IDC_EDIT_PORT, m_wndPort);
DDX_Control(pDX, IDC_EDIT_SEND, m_wndSend);
DDX_Control(pDX, IDC_BUTTON_SEND, m_ButtonSend);
DDX_Control(pDX, IDC_BUTTON_STOPCHAT, m_ButtonStopChat);
DDX_Control(pDX, IDC_EDIT_CHAT, m_wndChat);
DDX_Control(pDX, IDC_STATIC_COUNTPEOPLE, m_wndCountPeople);
}
BEGIN_MESSAGE_MAP(CChatCppDlg, CDialog)
ON_WM_SYSCOMMAND() // будем обрабатывать системные события
ON_WM_PAINT() //микрокоманды обновления клиентской области
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_RADIO_SERVER, OnBnClickedRadioServer) // макрокоманды вызова обработчика сообщений от кнопок
ON_BN_CLICKED(IDC_RADIO_CLIENT, OnBnClickedRadioClient)
ON_BN_CLICKED(IDC_BUTTON_STOPCHAT, OnBnClickedButtonStopchat)
ON_BN_CLICKED(IDC_BUTTON_SEND, OnBnClickedButtonSend)
ON_WM_CLOSE()
ON_EN_CHANGE(IDC_EDIT_NAME, &CChatCppDlg::OnEnChangeEditName)
ON_EN_CHANGE(IDC_EDIT_IP, &CChatCppDlg::OnEnChangeEditIp)
Изм.
Лист
№ докум.
Подпись
Дата
Лист
10
КУРСОВОЙ ПРОЕКТ
ON_EN_CHANGE(IDC_EDIT_PORT, &CChatCppDlg::OnEnChangeEditPort)
ON_EN_CHANGE(IDC_EDIT_SEND, &CChatCppDlg::OnEnChangeEditSend)
ON_BN_CLICKED(IDC_STATIC_COUNTPEOPLE, &CChatCppDlg::OnBnClickedStaticCountpeople)
ON_BN_CLICKED(IDC_BUTTON1, &CChatCppDlg::OnBnClickedButton1)
ON_LBN_SELCHANGE(IDC_LIST1, &CChatCppDlg::OnLbnSelchangeList1)
END_MESSAGE_MAP()
BOOL CChatCppDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//////////////////////////////////////////////////////////////////////////////
// Необходимая инициализация
SetWindowText("Нет сети!");
m_wndName.SetLimitText(12); // Ограничение количества вводимых символов.
m_wndName.SetWindowText(g_EmptyName);
m_wndSend.SetLimitText(200); // Ограничение количества вводимых символов.
m_wndIPAddress.SetWindowText("127.0.0.1"); // Адрес по умолчанию для тестирования.
m_wndPort.SetWindowText("1500"); // Порт по умолчанию.
m_ButtonStopChat.SetWindowText(g_strExitFromChat);
m_mainSocket.m_pParent = this;
return TRUE;
}
void CChatCppDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CChatCppDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); //контекст устройства для рисования
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// выравнивание значка по центру клиентского прямоугольника
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// вызов данной функции системой при перетаскивании окна
HCURSOR CChatCppDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
// Запускаем сервер
void CChatCppDlg::OnBnClickedRadioServer()
{
// Проверки несанкционированного запуска сервера:
// Если кнопка не в состоянии нажатой,
// если сокет в работе (т.е. только с нулевым сокетом можно начинать работать),
// очень неудобно если в чате все будут под одинаковыми именами.
if(m_ButtonStartServer.GetCheck() != BST_CHECKED) return;
if(m_mainSocket.m_hSocket != INVALID_SOCKET) return;
if(QueryName() == false)
{
AfxMessageBox("Введите свое имя для чата!");
StopChat();
return;
}
CString strPort;
m_wndPort.GetWindowText(strPort);
// Класс CAsyncSocket упрощает процедуру создания сокета,
// вкладывая в функцию Create() непосредственное создание
// сокета и связывание его с одним из IP адресом доступном на компьютере.
// atoi конвертирует строку ansi to int
if(m_mainSocket.Create(atoi(strPort)) == FALSE)
{
AfxMessageBox("Ошибка создания сервера!\nВозможно данный порт уже используется!");
StopChat();
Изм.
Лист
№ докум.
Подпись
Дата
Лист
11
КУРСОВОЙ ПРОЕКТ
}
Изм.
Лист
№ докум.
Подпись
Дата
Лист
12
КУРСОВОЙ ПРОЕКТ
else
{
// Вводим сокет в режим прослушивания запросов на подключения.
if(m_mainSocket.Listen() == FALSE)
{
StopChat();
}
else
{
// Если все в порядке.
DisabledControl(true);
SetWindowText("Сервер ждет подключения!");
// В чате только сервер.
m_wndCountPeople.SetWindowText("В чате 1 чел. online");
}
}
}
// Запускаем клиента
void CChatCppDlg::OnBnClickedRadioClient()
{
// Контроль несанкционированного запуска клиента:
// Если кнопка не в состоянии нажатой,
// если сокет в работе (т.е. только с нулевым сокетом можно начинать работать),
// очень неудобно если в чате все будут под одинаковыми именами..
if(m_ButtonStartClient.GetCheck() != BST_CHECKED) return;
if(m_mainSocket.m_hSocket != INVALID_SOCKET) return;
if(QueryName() == false)
{
AfxMessageBox("Введите свое имя для чата!");
StopChat();
return;
}
// Класс CAsyncSocket упрощает процедуру создания сокета,
// вкладывая в функцию Create() непосредственное создание
// сокета и связывание его с одним из IP адресом доступном на компьютере.
if(m_mainSocket.Create() == TRUE)
{
CString strAddress;
m_wndIPAddress.GetWindowText(strAddress);
CString strPort;
m_wndPort.GetWindowText(strPort);
if(m_mainSocket.Connect(strAddress, atoi(strPort)) == FALSE)
{
// В ассинхронном режиме код этой ошибки
// считается как ожидание события подключения,
// т.е. практически успешный возврат.
if(GetLastError() == WSAEWOULDBLOCK)
{
DisabledControl(false);
}
else
{
// иначе при возникновения какой либо ошибки останавливаем чат
StopChat();
}
}
}
}
// Нажали кнопку "Выйти из чата".
void CChatCppDlg::OnBnClickedButtonStopchat()
{
StopChat();
}
// Запрещает доступ к управлениям при работе
// приложения в режиме сервера или клиента.
// Цель запрета - избежать исключения от
// случайного нажатия "неправильных" кнопок.
void CChatCppDlg::DisabledControl(bool server)
{
// Запреты.
m_wndIPAddress.EnableWindow(FALSE);
m_wndPort.EnableWindow(FALSE);
m_ButtonSend.EnableWindow(FALSE);
if(server == true)
{
m_ButtonStopChat.SetWindowText(g_strStopChat);
m_ButtonStartClient.EnableWindow(FALSE);
}
else
{
m_ButtonStopChat.SetWindowText(g_strExitFromChat);
m_ButtonStartServer.EnableWindow(FALSE);
}
// Разрешения.
// Разрешить возможность выхода из чата.
m_ButtonStopChat.EnableWindow(TRUE);
}
// Разрешить доступ к управлениям после закрытия сокетов.
// Цель запрета - избежать исключения от
// случайного нажатия "неправильных" кнопок.
void CChatCppDlg::EnabledControl(void)
{
// Разрешения.
m_wndIPAddress.EnableWindow(TRUE);
m_wndPort.EnableWindow(TRUE);
m_ButtonStartClient.EnableWindow(TRUE);
m_ButtonStartServer.EnableWindow(TRUE);
// Запреты.
m_ButtonStopChat.EnableWindow(FALSE);
m_ButtonSend.EnableWindow(FALSE);
}
// Принимаем запросы на подключения
void CChatCppDlg::OnAccept(void)
{
CSock* pSock = new CSock;
pSock->m_pParent = this;
// Если все в порядке добавим рабочий сокет в список
// подключенных рабочих сокетов.
if(m_mainSocket.Accept(*pSock) == TRUE)
{
m_vecSockets.push_back(pSock);
m_ButtonSend.EnableWindow(TRUE);
SendCountPeople();
Изм.
Лист
№ докум.
Подпись
Дата
Лист
13
КУРСОВОЙ ПРОЕКТ
}
else
delete pSock;
SetWindowText("Сеть работает!");
}
// Выход из чата,
// если это сработало на стороне сервера,
// то это полная остановка чата.
void CChatCppDlg::StopChat(void)
{
// Отсылаем сигнал об отключении от чата.
SendDisconnect();
m_mainSocket.Close();
for(int i = 0; i < (int)m_vecSockets.size(); i++)
{
m_vecSockets[i]->Close();
delete m_vecSockets[i];
}
// Очистим вектор от ненужных элементов.
m_vecSockets.clear();
m_ButtonStartServer.SetCheck(BST_UNCHECKED);
m_ButtonStartClient.SetCheck(BST_UNCHECKED);
// Разрешим доступ к управлению для
// повторных попыток.
EnabledControl();
// В чате нет никого.
m_wndCountPeople.SetWindowText("В чате 0 чел.");
SetWindowText("Нет сети!");
}
// Отправка подготовленного сообщения.
void CChatCppDlg::OnBnClickedButtonSend()
{
CString strChat;
m_wndSend.GetWindowText(strChat);
SendChat(strChat);
}
// Извлечение сообщений из сети чата.
void CChatCppDlg::OnReceive(void)
{
SENDBUFFER sb;
if(m_ButtonStartServer.GetCheck() == BST_CHECKED)
{
// Сервер несет большую нагрузку при получении сообщений.
for(int index = 0; index < (int)m_vecSockets.size(); index++)
{
m_vecSockets[index]->Receive(&sb, sizeof(SENDBUFFER));
// Если кто-то отключился, удаляем этого клиента
// из списка доступных клиентов.
if(sb.typemessage == m_TypeMessage::tmDisconnect)
{
m_vecSockets[index]->Close();
delete m_vecSockets[index];
m_vecSockets.erase(m_vecSockets.begin() + index);
SendCountPeople();
Изм.
Лист
№ докум.
Подпись
Дата
Лист
14
КУРСОВОЙ ПРОЕКТ
// Отсылка принятого севером сообщения в сеть другим клиентам,
// как зеркало, клиент может работать с другими клиентами в
// сети только через сервер.
SendBuffer(sb, false);
break;
}
// Рассылаем сообщения клиента по сети чата.
if(sb.typemessage == m_TypeMessage::tmChat)
{
SendBuffer(sb, false);
break;
}
}
}
else if(m_ButtonStartClient.GetCheck() == BST_CHECKED)
{
m_mainSocket.Receive(&sb, sizeof(SENDBUFFER));
}
// Обработка принятого сообщения на основе
// его типа.
switch(sb.typemessage)
{
case m_TypeMessage::tmCountPeople:
{
m_wndCountPeople.SetWindowText("В чате " +
IntToStr(sb.countpeople) + " чел. online");
}
break;
case m_TypeMessage::tmChat:
{
CString strChat;
m_wndChat.GetWindowText(strChat);
strChat += " " + CString(sb.name) + ": " + CString(sb.buffer) + " ("+ IntToStr(sb.d)+ ":"+ IntToStr(sb.e)+":"+ IntToStr(sb.f)+ "-"+IntToStr(sb.a)+":"+ IntToStr(sb.b)+":" + IntToStr(sb.c)+")"+ "\r\n";
m_wndChat.SetWindowText(strChat);
int number_line = m_wndChat.GetLineCount();
m_wndChat.LineScroll(number_line);
}
break;
case m_TypeMessage::tmDisconnect:
{
CString strChat;
m_wndChat.GetWindowText(strChat);
// Если принято сообщение об остановки чата(отключении сервера),
// изменим содержимое сообщения.
if(sb.stopchat == true)
{
StopChat();
strChat += " " + CString(sb.name) + ": Чат остановлен!" + "\r\n"+ "==============================" + "\r\n";
}
else
{
Изм.
Лист
№ докум.
Подпись
Дата
Лист
15
КУРСОВОЙ ПРОЕКТ
strChat += " " + CString(sb.name) + " - покинул(а) чат!" + "\r\n";
}
FILE* fo;
fo = fopen("client.txt","ab");
fprintf( fo,strChat);
m_wndChat.SetWindowText(strChat);
int number_line = m_wndChat.GetLineCount();
m_wndChat.LineScroll(number_line);
}
break;
default:
AfxMessageBox("Неизвестное сообщение!");
break;
}
}
// При закрытии приложения отправим в чат
// информацию об отключении чатующего.
void CChatCppDlg::OnClose()
{
StopChat();
CDialog::OnClose();
}
// Послать строку-сообщение в чат.
void CChatCppDlg::SendChat(CString strMessage)
{
SENDBUFFER sb;
int len = strMessage.GetLength();
memcpy(sb.buffer, strMessage.GetBuffer(), sizeof(TCHAR)*len);
m_wndName.GetWindowText(strMessage);
len = strMessage.GetLength();
memcpy(sb.name, strMessage.GetBuffer(), sizeof(TCHAR)*len);
sb.typemessage = m_TypeMessage::tmChat;
SendBuffer(sb, true);
}
// Послать буфер подготовленного сообщения в сеть.
void CChatCppDlg::SendBuffer(SENDBUFFER sb, bool toserver)
{
// Если сокет не создан, нечего делать в этой функции.
if(m_mainSocket.m_hSocket == INVALID_SOCKET) return;
if(m_ButtonStartServer.GetCheck() == BST_CHECKED)
{
for(int i = 0; i < (int)m_vecSockets.size(); i++)
{
int send = m_vecSockets[i]->Send(&sb, sizeof(SENDBUFFER));
if(send == sizeof(SENDBUFFER))
{
m_wndSend.SetWindowText("");
}
}
// Если непосредственно отправку осуществляет сервер,
// отобразим его сообщение в его же окне отправки,
// флаг toserver необходим поскольку данная функция
Изм.
Лист
№ докум.
Подпись
Дата
Лист
16
КУРСОВОЙ ПРОЕКТ
// может работать в режиме зеркала см. CChatCppDlg::OnReceive(void).
if(toserver == true )
{
if(sb.typemessage == m_TypeMessage::tmChat)
{
CString strChat;
m_wndChat.GetWindowText(strChat);
strChat += " " + CString(sb.name) + ": " + CString(sb.buffer) + " ("+ IntToStr(sb.d)+ ":"+ IntToStr(sb.e)+":"+ IntToStr(sb.f)+ "-"+IntToStr(sb.a)+":"+ IntToStr(sb.b)+":" + IntToStr(sb.c)+")"+ "\r\n";
m_wndChat.SetWindowText(strChat);
int number_line = m_wndChat.GetLineCount();
m_wndChat.LineScroll(number_line);
}
if(sb.typemessage == m_TypeMessage::tmDisconnect)
{
CString strChat;
m_wndChat.GetWindowText(strChat);
strChat += " " + CString(sb.name) + ": " + "Чат остановлен!" + "\r\n" + "===============================\r\n";
FILE* fo;
fo = fopen("server.txt","ab");
fprintf( fo,strChat);
m_wndChat.SetWindowText(strChat);
int number_line = m_wndChat.GetLineCount();
m_wndChat.LineScroll(number_line);
}
}
}
else if(m_ButtonStartClient.GetCheck() == BST_CHECKED)
{
int send = m_mainSocket.Send(&sb, sizeof(SENDBUFFER));
if(send == sizeof(SENDBUFFER))
m_wndSend.SetWindowText("");
}
}
// Формируем и отправляем сообщение об отключении от сети.
void CChatCppDlg::SendDisconnect(void)
{
CString strChat;
m_wndChat.GetWindowText(strChat);
SENDBUFFER sb;
CString s;
m_wndName.GetWindowText(s);
int len = s.GetLength();
memcpy(sb.name, s.GetBuffer(), sizeof(TCHAR)*len);
sb.typemessage = m_TypeMessage::tmDisconnect;
// Отсоединение сервера останавливает чат.
if(m_ButtonStartServer.GetCheck() == BST_CHECKED)
sb.stopchat = true;
SendBuffer(sb, true);
}
Изм.
Лист
№ докум.
Подпись
Дата
Лист
17
КУРСОВОЙ ПРОЕКТ
// Событие подключения, происходит на стороне клиента.
void CChatCppDlg::OnConnect(BOOL Error)
{
if(Error == TRUE)
{
AfxMessageBox("Попытка подключения была отвергнута!\nВозможно сервер еще не создан!");
StopChat();
}
else
{
m_ButtonSend.EnableWindow(TRUE);
SetWindowText("Сеть работает!");
}
}
Изм.
Лист
№ докум.
Подпись
Дата
Лист
18
КУРСОВОЙ ПРОЕКТ
// Сервер отправляет клиентам количество людей в чате.
void CChatCppDlg::SendCountPeople(void)
{
int countpeople = 1/*сервер*/ + (int)m_vecSockets.size()/*клиенты*/;
m_wndCountPeople.SetWindowText("В чате " +
IntToStr(countpeople) + " чел. online");
// Отправим сообщение о количествах людей в чате.
SENDBUFFER sb;
sb.typemessage = m_TypeMessage::tmCountPeople;
sb.countpeople = countpeople;
for(int i = 0; i < (int)m_vecSockets.size(); i++)
{
int send = m_vecSockets[i]->Send(&sb, sizeof(SENDBUFFER));
}
}
// Запрос имени чатующего перед созданием сокета.
bool CChatCppDlg::QueryName(void)
{
CString strName;
m_wndName.GetWindowText(strName);
if(strName == g_EmptyName || strName.IsEmpty() == true)
return false;
return true;
}
void CChatCppDlg::OnEnChangeEditName()
{
}
void CChatCppDlg::OnEnChangeEditIp(){}
void CChatCppDlg::OnEnChangeEditPort(){}
void CChatCppDlg::OnEnChangeEditSend() {}
void CChatCppDlg::OnBnClickedStaticCountpeople()
{}
void CAboutDlg::OnBnClickedOk()
{
OnOK();
}
void CChatCppDlg::OnEnChangeEditChat() {}
void CChatCppDlg::OnBnClickedButton1()
{
system ("C:\\\\Users\\Администратор\\Desktop\\client_start\\ChatCpp\\client.txt");
}
Изм.
Лист
№ докум.
Подпись
Дата
Лист
19
КУРСОВОЙ ПРОЕКТ
3. Разработка и тестирование программного комплекса
Результатом работы программы стал обмен текстовой информацией между удаленными компьютерами локальной сети. Окно первого запуска изображено на рисунке 2.
Рисунок 2. Окно первого запуска
Окно сервера изображено на рисунке 3.
Рисунок 3. Окно сервера
Окно клиента изображено на рисунке 4.
Рисунок 4. Окно клиента
Проверка отправки и прихода сообщений изображено на рисунке 6.
Изм.
Лист
№ докум.
Подпись
Дата
Лист
20
КУРСОВОЙ ПРОЕКТ
Рисунок 5. Проверка отправки и прихода сообщений
Изм.
Лист
№ докум.
Подпись
Дата
Лист
21
КУРСОВОЙ ПРОЕКТ
К приемуществам данной программы можно отнести:
Недостатки:
Для корректной работы программы использовались следующие системы защиты:
Рисунок 6. Проверка ввода имени
Изм.
Лист
№ докум.
Подпись
Дата
Лист
22
КУРСОВОЙ ПРОЕКТ
Рисунок 7. Проверка на подключения клиента к серверу
При нажатии кнопки архива сообщений, появляется окно истории всех сообщений пользователя (сервера), в зависимости от типа подключения (рисунок 8):
Рисунок 8. Архив сообщений клиента
Заключение
В результате выполнения курсового проекта, получили программу пересылки текстовых сообщений по локальной сети.
Были изучены компоненты классов CAboutDlg, CSock, ChatCppApp, CChatCppDlg и т.д. Ознакомились со специальными методами для работы с этими компонентами, научились обрабатывать реакцию этих компонентов на события, научились эффективно и эстетично использовать рабочее пространство формы и освоились со специфичностью написания программ . VC++связывает с каждым включаемым в программу окном собственный модуль и таким способом локализует все свойства окна в отдельной программной единице. Выяснили, что основная программа весьма специфична: она содержит перечень всех используемых в программе модулей и несколько исполняемых операторов, обеспечивающих создание нужных окон и связь программы с Windows. Вся основная работа программы управляется кодом, содержащимся в модулях.
Изм.
Лист
№ докум.
Подпись
Дата
Лист
23
КУРСОВОЙ ПРОЕКТ
Список использованной литературы
Изм.
Лист
№ докум.
Подпись
Дата
Лист
24
КУРСОВОЙ ПРОЕКТ
Изм.
Лист
№ докум.
Подпись
Дата
Лист
25
КУРСОВОЙ ПРОЕКТ
Приложение А
Изм.
Лист
№ докум.
Подпись
Дата
Лист
26
КУРСОВОЙ ПРОЕКТ
Диаграмма классов
Изм.
Лист
№ докум.
Подпись
Дата
Лист
27
КУРСОВОЙ ПРОЕКТ
Приложение Б
Изм.
Лист
№ докум.
Подпись
Дата
Лист
28
КУРСОВОЙ ПРОЕКТ
Диаграмма прецедентов
Изм.
Лист
№ докум.
Подпись
Дата
Лист
29
КУРСОВОЙ ПРОЕКТ
Приложение В
Изм.
Лист
№ докум.
Подпись
Дата
Лист
30
КУРСОВОЙ ПРОЕКТ
Диаграмма компонентов
Приложение Г
Изм.
Лист
№ докум.
Подпись
Дата
Лист
31
КУРСОВОЙ ПРОЕКТ
Изм.
Лист
№ докум.
Подпись
Дата
Лист
32
КУРСОВОЙ ПРОЕКТ
Диаграмма взаимодействий
Изм.
Лист
№ докум.
Подпись
Дата
Лист
33
КУРСОВОЙ ПРОЕКТ
Приложение Д
Диаграмма развёртывания
Изм.
Лист
№ докум.
Подпись
Дата
Лист
34
КУРСОВОЙ ПРОЕКТ
Изм.
Лист
№ докум.
Подпись
Дата
Лист
35
КУРСОВОЙ ПРОЕКТ
Приложение Е
Изм.
Лист
№ докум.
Подпись
Дата
Лист
36
КУРСОВОЙ ПРОЕКТ
Протокол тестирования
Приложение Ж
Изм.
Лист
№ докум.
Подпись
Дата
Лист
37
КУРСОВОЙ ПРОЕКТ
Приложение З
Изм.
Лист
№ докум.
Подпись
Дата
Лист
39
КУРСОВОЙ ПРОЕКТ