Сетевое приложение почтового отделения

Автор: Пользователь скрыл имя, 22 Мая 2013 в 23:59, курсовая работа

Описание работы

Производительность и пропускная способность корпоративной сети определяется многими факторами:
– выбором серверов и рабочих станций, их удалением друг от друга;
– качеством и подбором каналов связи, сетевого оборудования;
– выбором сетевого протокола передачи данных, серверных операционных систем и операционных систем рабочих станций, аппаратной части серверов и ее конфигураций;

Содержание

ВВЕДЕНИЕ 3
1 ИЗУЧЕНИЕ ПРЕДМЕТНОЙ ОБЛАСТИ 5
1.1 Описание поставленной задачи 5
1.2 Актуальность исследуемой задачи 6
1.3 Современное состояние исследуемой задачи 6
1.4 Обзор метод и решений подобных задач 11
1.5 Постановка задачи. Системные требования 13
2 ПРОЕКТИРОВАНИЕ СТРУКТУРЫ И АРХИТЕКТУРЫ
ПРОГРАММНОГО ПРОДУКТА 15
2.1 Разработка компьютерной сети 15
2.2 Спецификация и расчет себестоимости спроектированной сети 18
2.3 Проектирование сети с помощью программы NetCracker 19
2.4 Выбор средств разработки клиент-серверного приложения 22
3 РЕАЛИЗАЦИЯ ПРОГРАММНОГО ПРОДУКТА 24
3.1 Описание логической структуры программного продукта 24
3.2 Реализация программного продукта, основные алгоритмы 26
ЗАКЛЮЧЕНИЕ 34
СПИСОК ИСПОЛЬЗУЕМОЙ ЛИТЕРАТУРЫ 35

Работа содержит 1 файл

Пояснительная записка_.docx

— 2.94 Мб (Скачать)

– добавление в базу данных, хранящуюся в текстовых файлах, новых учётных записей;

– добавление новых квитанций;

– удаление квитанций из базы данных;

– формирование бланков отчетов в HTML.

Первоначальным этапом в работе клиентского приложения является аутентификация пользователей. Это даёт возможность разграничить права пользователей: пользователь admin имеет право редактировать содержимое файлов, перезапускать сервер удаленно, изменять пароли, добавлять и удалять учетные записи. Другим учетным записям доступны функции, непосредственно связанные с выполнением их профессиональной деятельности, то есть оказание всевозможных почтовых услуг.

После процедуры аутентификации следует  этап непосредственного взаимодействия клиентского и серверного приложения.

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

Так же реализована функция просмотра и поиска квитанций. Функция реализована таким образом, что клиентское приложение получает список всех квитанций, хранящихся на сервере. Данные с сервера извлекаются после выбора необходимой квитанции из списка.

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

Согласно техническому заданию  в серверном приложении реализована  функция удаления анкет клиентов из базы данных.

Схема взаимодействия клиентского  и серверного приложений представлена на рисунке 3.1.

Рисунок 3.1 – Схема взаимодействия клиентского и серверного приложений

 

3.2 Реализация программного продукта, основные алгоритмы

Программный комплекс, реализующий информационную систему почтового отделения, является сетевым. Основными алгоритмами являются алгоритмы, связанные с передачей данных по сети.

Соединение клиентского приложения с серверным приложением осуществляется при помощи методов класса TcpListener.

Для работы с BinaryFormatter, TcpListener, NetworkStream, FileStream файлами необходимо объявить пространства имен:

usingSystem.Net.Sockets;

using System.Net;

using System.IO;

usingSystem.Runtime.Serialization;

usingSystem.Runtime.Serialization.Formatters;

usingSystem.Runtime.Serialization.Formatters.Binary;

 

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

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

Void Read_Login_Info()

        {

            //Загружаем из файла в память  информацию о пользовательских  данных

string[] logins = File.ReadAllText(Application.StartupPath + “\\users.txt”).Split(new string[] { “\r\n” }, StringSplitOptions.RemoveEmptyEntries);

            for (int I = 0; I< logins.Length; i++)

            {

                string[] Temp_Data = logins[i].Split(‘:’);

//Запись в словарь  данных о пользователях.

Login_Dict.Add(Temp_Data[0], Temp_Data[1]);

}

        }

 

Метод Read_Config() позволяет считать данные из файла Config.txt, разделяет их на строки. Далее среди всех строк происходит поиск строки, начинающейся со слов «port:», то есть нахождение в файле значения порта. Из найденной строки вырезается слово «port:», а оставшаяся часть строки конвертируется в целочисленную переменную.

Void Read_Config()

        {

            //Считывание информации из конфигурационного  файла и разбиение её на  строки для считывания конфигурации  приложения

config = File.ReadAllText(Application.StartupPath + “\\config.txt”).Split(new string[] { “\r\n” }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string str in config)

            {

                if (str.IndexOf(“port:”) == 0)

                {

                    string temp_str = str.Replace(“port:”, “”);

//Заменяем port: на пустую  строку и получаем номер порта

port = int.Parse(temp_str);

                }

                if (str.IndexOf(“percent:”) == 0)

                {

                    string temp_str = str.Replace(“percent:”, “”);

                    percent = double.Parse(temp_str);

                }

                if (str.IndexOf(“tarif_zarubej:”) == 0)

                {

                    string temp_str = str.Replace(“tarif_zarubej:”, “”);

                    tarif_zarubej = double.Parse(temp_str);

                }

                if (str.IndexOf(“tarif_gorod:”) == 0)

                {

                    string temp_str = str.Replace(“tarif_gorod:”, “”);

                    tarif_gorod = double.Parse(temp_str);

                }

                if (str.IndexOf(“tarif_strana:”) == 0)

                {

                    string temp_str = str.Replace(“tarif_strana:”, “”);

                    tarif_strana = double.Parse(temp_str);

}

            }

        }

 

Метод Load_files() позволяет осуществить загрузка списка файлов (квитанций), хранящихся на сервере. Все квитанции распределяются в разные listBox. Считывается информация о логинах. Сервер стартует.

 

//Загрузка файлов в  окно сервера

        void load_files()

{

            try

            {

                money_list.Items.Clear();

                posts_list.Items.Clear();

                letter_list.Items.Clear();

//Сканируем директорию  хранения файлов для загрузки  файлов в окно

DirectoryInfo DI = new DirectoryInfo(Application.StartupPath + “\\Papers”);

                FileInfo[] Files = DI.GetFiles(“*.html”, SearchOption.TopDirectoryOnly);

                foreach (FileInfo A in Files)

                {

                    if (A.Name.Contains(“письма”))

                        letter_list.Items.Add(A.Name);

                    if (A.Name.Contains(“перевода”))

                        money_list.Items.Add(A.Name);

                    if (A.Name.Contains(“посылки”))

                        posts_list.Items.Add(A.Name);

}

            }

            catch

            { }

        }

 

Любое действие записывается в лог-файл.

//Метод записи логов  программы в файл

void WriteLog()

        {

            string temp = DateTime.Now.ToShortTimeString() + “>>“ + work_info.Text + “\r\n”;

            if (!Directory.Exists(Application.StartupPath + “\\logs\\”))

                Directory.CreateDirectory(Application.StartupPath + “\\logs\\”);

            File.AppendAllText(Application.StartupPath + “\\logs\\” + DateTime.Now.ToShortDateString() + “_log.txt”, temp, Encoding.Default);

}

 

Значительную часть занимает метод  обработки запросов от клиентов. Он представляет собой бесконечный  цикл, в котором происходит постоянное считывание данных с клиента. Данные от клиента разбиваются для последующей обработки и записываются в строку Working. Она анализируется. Клиент присылает данные в определенном формате в зависимости от необходимой операции. Если строка содержит слово «LOGIN_DATA:», то клиент запрашивает информацию об авторизации. Сервер проверяет. Попытка извлечения пароля. В методе происходит попытка, сравнивается присланный пароль, и тот, который находится в массиве Dictionary.

 

//Авторизация

                if (Working.Contains(“LOGIN_DATA:”))

{

                    //Считывание данных от клиента  и разбиение их для обработки

Working = Working.Replace(“LOGIN_DATA:”, “”);

                    string[] login_and_pass = Working.Split(‘|’);

//Получение логина и  пароля пользователя

                    string login = login_and_pass[0];

string pass = login_and_pass[1];

string temp_pass = «»;

                    //Извлекаем из словаря пароль  по данному логину

Login_Dict.TryGetValue(login, out temp_pass);

//Если извлеченный пароль  совпадает с паролем в словаре  – авторизация удалась

                    if (temp_pass == pass)

                    {

                        Work_Socket.Send(Encoding.Default.GetBytes(«Логин и пароль успешно подтверждены!»));

                        work_info.Text = «Пользователь УСПЕШНО авторизовался под именем « + login;

                        WriteLog();

                    }

                    //Авторизация не удалась.

Else

                    {

                        Work_Socket.Send(Encoding.Default.GetBytes(«Авторизация не удалась!»));

                        work_info.Text = «Неудачная попытка авторизации под именем « + login + «и паролем « + pass;

                        WriteLog();

                    }

                }

 

Если строка содержит слово «GIVEMEPERCENT», то клиент запрашивает процентную ставку – переменная percent преобразуется в массив byte и отсылается обратно.

If (Working == “GIVEMEPERCENT”)

                {

                    SND = Encoding.Default.GetBytes(percent.ToString());

                    Work_Socket.Send(SND);

work_info.Text = “Назапроспроцентнойставкипереводовотосланответ:  “ + percent.ToString();

WriteLog();

                }

 

Если строка содержит слово «WRITE_FILE~», значит клиент присылает квитанцию, которую оплатили и ее нужно сохранить. К тому же присылается файл с квитанцией и сохраняет ее в соответствующий файл (вид_операции | № квитанции). Сохраняем текст квитанции в HTML-файл.

If (Working.IndexOf(“WRIRE_FILE~”) == 0)

{

                    //Запись в файл информации  о переводе

string[] write_info = Working.Split(‘~’);

                    string Info_To_Save = write_info[1];

                    if (write_info[2].Contains(“отправка”))

                    {

                        File.AppendAllText(Application.StartupPath + “\\otpravka.txt”, Info_To_Save + “\r\n”, Encoding.Default);

                    }

                    if (write_info[2].Contains(“приём”))

                    {

                        File.AppendAllText(Application.StartupPath + “\\poluchenie.txt”, Info_To_Save + “\r\n”, Encoding.Default);

                    }

                    Working = write_info[2];

                    Regex get_title = new Regex(@”<title>.+</title>”, RegexOptions.Compiled);

                    string nazv = get_title.Match(Working).Value;

                    nazv = nazv.Replace(“<title>”, “”);

                    nazv = nazv.Replace(“</title>”, “”);

//Сохраняем файл с  созданием папки.

If (!Directory.Exists(Application.StartupPath + “\\Papers”))

                        Directory.CreateDirectory(Application.StartupPath + “\\Papers”);

                    File.AppendAllText(Application.StartupPath + “\\Papers\\” + nazv + “.html”, Working, Encoding.Default);

work_info.Text = «Клиент прислал квитанцию: « + nazv;

                    WriteLog();

                }

 

Алгоритм выдачи определенного  вида услуг заключается в считывании из файла poluchenie.txt всей информации и затем по присланному клиентом сообщению производится замена указанного клиентом вида услуги с номером квитанции. Удаляется файл со старым содержимым и создается новый файл с расширением *.txt. Выданная посылка помечается знаком «*» в начале имени файла.

             //Выдача посылки\перевода\письма. Изменение  данных в файле.

If (Working.IndexOf(“TAKE_OFF~”) == 0)

{

                    try

                    {

                        string[] temp_info = Working.Split(‘~’);

                        string[] identify_info = temp_info[1].Split(‘|’);

work_info.Text = «Пользователь запросил выдачу товара по квитанции № « + identify_info[1];

                        WriteLog();

                        string content = «»;

                        //Ставим * в качестве пометки о  выданном товаре

content = File.ReadAllText(Application.StartupPath + “\\poluchenie.txt”, Encoding.Default);

                        content = content.Replace(temp_info[1], “*” + temp_info[1]);

                        //Удаляемстарыйфайл

                        File.Delete(Application.StartupPath + “\\poluchenie.txt”);

                        //Записываемновыйфайл

                        File.AppendAllText(Application.StartupPath + “\\poluchenie.txt”, content, Encoding.Default);

work_info.Text = «Информация в файле успешно сохранена! Код №» + identify_info[1] + « успешно списан со склада.»;

                        WriteLog();

Work_Socket.Send(Encoding.Default.GetBytes(«Информация в файле успешно сохранена!Код №» + identify_info[1] + « успешно списан со склада.»));

                    }

                    catch

                    {

 

                    }

                }

 

При запуске клиентского приложения вызывается метод Read_Config(), позволяющий считать информацию из конфигурационного файла и разбить ее на строки для считывания конфигурации приложения: IP и PORT.

void Read_Config()

        {

            //Считывание информации из конфигурационного  файла и разбиение её на  строки для считывания конфигурации  приложения

config = File.ReadAllText(Application.StartupPath + "\\config.txt").Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string str in config)

            {

                if (str.IndexOf("port:") == 0)

                {

                    string temp_str = str.Replace("port:", "");

//Заменяем port: на пустую  строку и получаем номер порта

port = int.Parse(temp_str);

                }

                if (str.IndexOf("ip:") == 0)

                {

                    string temp_str = str.Replace("ip:", "");

//Заменяем port: на пустую  строку и получаем номер порта

                    ip = temp_str;

                }

            }

        }

 

Для вывода отчетов было решено использовать средства языка разметки HTML. Создание отчета происходит в процессе построения HTML страницы, содержащей данные, введенные с формы. Данные в отчет заносятся после нажатия на кнопку «сформировать квитанцию». При необходимости узнать информацию с сервера происходит предварительный запрос нужной информации на сервере. В дальнейшем HTML содержимое (строка) сохраняется в файл и отображается в Webbrowser, при этом отчет также передается на сервер для хранения и там. Код данной функции приведен ниже:

Информация о работе Сетевое приложение почтового отделения