Создание клиент-серверного приложения

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

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 22.08.2016
Размер файла 4,7 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

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

Должно быть обеспечено надежное заземление защитного фильтра монитора ПК. Наиболее правильным способом является соединение фильтра с корпусом системного блока ПК. Не рекомендуется соединение защитного экранного фильтра с другими зануленными электроустановками.

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

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

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

Оптимальная планировка рабочего места -- планировка, при которой полностью разделены зоны местонахождения пользователя ПК и зоны расположения кабелей электропитания технических средств рабочего места, включая розетки сетевого электропитания.

При размещении в помещении нескольких рабочий мест с ПК необходимо учитывать, что расстояние между боковыми поверхностями соседних мониторов должно составлять не менее 1,2 м, а между тыльной поверхностью одного монитора и экраном другого - не менее 2,0 м.

При размещении значительного числа рабочих мест в помещении для обеспечения электромагнитной безопасности необходимо обеспечивать:

- автономное размещение отдельных рабочих мест, их автономное электропитание;

- максимально возможная удаленность от каждого пользователя сетевых элементов и аппаратуры соседних рабочих мест.

6.3 Санитарно-гигиенические параметры рабочего места

Требования к микроклимату рабочих мест

На рабочем месте пользователя должны обеспечиваться оптимальные параметры микроклимата, которые установлены в СанПиН 2.2.4.548-96 «Гигиенические требования к микроклимату производственных помещений» [16]. На работах, производимых сидя и не требующих физического напряжения, температура воздуха должна быть в холодный период года от 22 до 24 ?С, теплый период года -- от 23 до 25 ?С. Относительная влажность воздуха на постоянных рабочих местах должна составлять 40-60%, скорость движения воздуха должна быть 0,1 м/с. Для повышения влажности воздуха в помещениях следует применять увлажнители воздуха.

Требования к освещению рабочих мест

Согласно СанПиН 2.2.1/2.1.1.1278-03 «Гигиенические требования к естественному, искусственному и совмещенному освещению жилых и общественных зданий» [17] освещенность на поверхности стола в зоне размещения рабочего документа должна быть 300-500 лк. Освещение не должно создавать бликов на поверхности экрана. Освещенность поверхности экрана не должна быть более 300 лк.

Следует ограничивать неравномерность распределения яркости в поле зрения пользователя ПЭВМ при этом соотношение яркости между рабочими поверхностями не должно превышать 3:1-5:1, а между рабочими поверхностями и поверхностями стен и оборудования -- 10:1.

Коэффициент пульсации не должен превышать 5%.

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

При рядном размещении рабочих столов не допускается расположение экранов дисплеев навстречу друг другу из-за их взаимного отражения, в противном случае между столами следует устанавливать перегородки.

Требования к уровням шума и вибрации на рабочих местах

В производственных помещениях при выполнении основных или вспомогательных работ с использованием ПЭВМ уровни шума на рабочих местах не должны превышать предельно допустимых значений, установленных для данных видов работ в соответствии с СН 2.2.4/2.1.8.562-96 «Шум на рабочих местах, в помещениях жилых, общественных зданий и на территории жилой застройки» [18].

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

При выполнении основной работы на мониторах и ПЭВМ (диспетчерские, операторские, залы вычислительной техники и т. д.), где работают инженерно-технические работники, уровень шума не должен превышать 60 дБА, в помещениях операторов ЭВМ (без дисплеев) -- 65 дБА, на рабочих местах в помещениях, где размещаются шумные агрегаты вычислительных машин -- 75 дБА.

Поскольку каждый ПК оснащен системами охлаждения, которые, в свою очередь, содержат источники вибрации; то ПК можно отнести к источнику общей вибрации 3 категории (электрические машины). При выполнении работ с использованием ПК в производственных помещениях уровень вибрации не должен превышать допустимых значений вибрации для рабочих мест (категория 3, тип “в”) в соответствии с действующими санитарно-эпидемиологическими нормативами, указанными в СН 2.2.4/2.1.8.566-96 «Производственная вибрация, вибрация в помещениях жилых и общественных зданий» [19].

Требования к уровням электромагнитных полей на рабочих местах

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

Временные допустимые уровни ЭМП, создаваемых ПЭВМ на рабочих местах пользователей установлены в СанПиН 2.2.2/2.4.1340-03 «Гигиенические требования к персональным электронно-вычислительным машинам и организации работы» и представлены в таблице 6.1.

Таблица 6.1 - Временные допустимые уровни ЭМП, создаваемых ПЭВМ на рабочих местах

Наименования параметров

ВДУ

Напряжённость электрического поля

в диапазоне 5 Гц. - 2 кГц.

25 В./м.

в диапазоне 2 кГц. - 400 кГц.

2,5 В./м.

Плотность магнитного потока

в диапазоне 5 Гц. - 2 кГц.

250 нТл.

в диапазоне 2 кГц. - 400 кГц.

25 нТл.

Напряжённость электростатического поля

15 кВ./м.

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

К пассивным системам защиты от ЭМИ относятся:

- защита временем;

- защита расстоянием;

- рациональное размещение установок в рабочем помещении;

- выделение зон излучения;

- применение средств предупреждающей сигнализации (световая, звуковая);

- установление рациональных режимов эксплуатации установок и

работы обслуживающего персонала.

К активным системам защиты от ЭМИ относятся:

- уменьшение параметров излучения непосредственно в самом источнике излучения;

- экранирование источника излучения;

- экранирование рабочего места;

- применение средств индивидуальной защиты (например, защитные очки).

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

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

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

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

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

Выделение зон излучения производится на основании инструментальных замеров интенсивности ЭМИ. Источники ЭМИ ограждают или отмечают границу зоны яркой краской на полу помещения.

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

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

Режим труда и отдыха при работе с ПК

Режим труда и отдыха предусматривает соблюдение определенной длительности непрерывной работы на ПК и перерывов, регламентированных с учетом продолжительности рабочей смены, видов и категории трудовой деятельности. Параметры оптимального режима труда и отдыха представлены в СанПиН 2.2.2/2.4.1340-03 «Гигиенические требования к персональным электронно-вычислительным машинам и организации работы».

Виды трудовой деятельности на ПК разделяются на 3 группы:

- группа А - работа по считыванию информации с экрана с предварительным запросом;

- группа Б - работа по вводу информации;

- группа В - творческая работа в режиме диалога с ПК.

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

Категории тяжести и напряженности работы на ПК определяются уровнем нагрузки за рабочую смену:

- для группы А -- по суммарному числу считываемых знаков;

- для группы Б -- по суммарному числу считываемых или вводимых знаков;

- для группы В -- по суммарному времени непосредственной работы на ПК.

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

Таблица 6.2 - Виды категорий трудовой деятельности с ПК

Категория работы с ВДТ или ПЭВМ

Уровень нагрузки ха рабочую смену при видах работ с ВДТ

Суммарное время регламентированных перерывов, (мин)

группа А, кол-во знаков

группа Б, кол-во знаков

группа В, час

8 час. смена

12 час. смена

I категория

до 20000

до 15000

до 2

50

80

II категория

до 40000

до 30000

до 4

70

110

III категория

до 60000

до 40000

до 6

90

140

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

При 8-часовой рабочей смене и работе на ПК регламентированные перерывы следует устанавливать:

- для первой категории работ через 2 часа от начала смены и через 2 часа после обеденного перерыва продолжительностью 15 минут каждый;

- для второй категории работ -- через 2 часа от начала рабочей смены и через 1,5-2,0 часа после обеденного перерыва продолжительностью 15 минут каждый или продолжительностью 10 минут через каждый час работы;

- для третьей категории работ -- через 1,5- 2,0 часа от начала рабочей смены и через 1,5-2,0 часа после обеденного перерыва продолжительностью 20 минут каждый или продолжительностью 15 минут через каждый час работы.

При 12-часовой рабочей смене регламентированные перерывы должны устанавливаться в первые 8 часов работы аналогично перерывам при 8-часовой рабочей смене, а в течение последних 4 часов работы, независимо от категории и вида работ, каждый час продолжительностью 15 минут.

Продолжительность непрерывной работы на ПК без регламентированного перерыва не должна превышать 2 часа.

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

Эффективными являются нерегламентированные перерывы (микропаузы) длительностью 1-3 минуты.

Регламентированные перерывы и микропаузы целесообразно использовать для выполнения комплекса упражнений и гимнастики для глаз, пальцев рук, а также массажа. Комплексы упражнений целесообразно менять через 2-3 недели.

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

6.4 Пожарная безопасность

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

Горючими компонентами на помещениях с ПК являются: строительные материалы для акустической и эстетической отделки помещений, перегородки, двери, полы, корпус и детали самих ПК, изоляция кабелей и др. Следовательно, в таких помещениях наиболее вероятны пожары классов: А (горение твердых веществ) и Е (горение электроустановок).

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

- перегрузка проводов;

- большие переходные сопротивления;

- возникновение искрения;

- короткое замыкание.

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

Для большинства помещений с ПЭВМ установлена категория пожарной опасности В (пожароопасность).

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

Согласно ППБ-01-03, помещения класса А рекомендуется оснащать воздушно-пенными и порошковыми огнетушителями. Помещения класса Е углекислотными и порошковыми огнетушителями.

В замкнутых помещениях объемом до 50 м2 вместо переносных огнетушителей (или в дополнение к ним) можно использовать подвесные самосрабатывающие порошковые огнетушители ОСП. В помещениях большего объема огнетушителями ОСП рекомендуется защищать самые важные объекты.

Пожарная безопасность должна обеспечиваться, в том числе и организационно-техническими мероприятиями.

Организационно-технические мероприятия включают в себя:

- организацию пожарной охраны (профессиональной, добровольной);

- обучение рабочих и служащих правилам пожарной безопасности;

- составление инструкций о порядке работы с пожароопасными веществами и материалами;

- отработку действий администрации, рабочих и служащих в случае возникновения пожара и эвакуации людей;

- применение средств наглядной агитации по обеспечению пожарной безопасности.

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

В зависимости от масштаба задач, которые решает охранно-пожарная сигнализация, в ее состав входит оборудование трех основных категорий:

- Оборудование централизованного управления охранно-пожарной сигнализацией;

- Оборудование сбора и обработки информации с датчиков охранно-пожарной сигнализации: приборы приемно-контрольные охранно-пожарные (панели);

- Сенсорные устройства-датчики и извещатели охранно-пожарной сигнализации.

Охранно-пожарная сигнализация состоит из двух подсистем:

- охранная сигнализация, предназначенная для контроля доступа;

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

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

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

Все устройства охранно-пожарной сигнализации должны обеспечиваться бесперебойным электропитанием.

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

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

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

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

Заключение

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

Разработанная система, базирующаяся на разработанном протоколе LIMone, состоит из трех программ, взаимодействующих по каналу связи путем отправки пакетов в рамках протокола. Данная система удовлетворяет всем заявленным требованиям, а именно:

- осуществляет мгновенную передачу сообщений от клиента к клиенту, либо внутри одной группы, посредством сервера;

- осуществляет передачу файлов от клиента к клиенту;

- сохраняет сообщения на сервере в случае невозможности мгновенной доставки адресату;

- обеспечивает безопасную авторизацию сотрудника и администратора на сервере;

- предоставляет единый контакт-лист, отражающий структуру отделов организации;

- предоставляет возможность модификации контакт-листа и управления сервером с использованием администрирующего клиента;

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

Приложение А Библиография

1 Bimoid // Bimoid - сервер и мессенджер для вашей сети. URL: http://www.bimoid.com/ (дата обращения: 24.05.2013).

2 IRC // Википедия -- свободная энциклопедия. URL: http://ru.wikipedia.org/wiki/IRC (дата обращения: 24.05.2013).

3 XMPP // Википедия -- свободная энциклопедия. URL: http://ru.wikipedia.org/wiki/XMPP (дата обращения: 24.05.2013).

4 Протокол OSCAR // OSCAR: Documentation. URL: http://oscar.6dreams.net/ (дата обращения: 24.05.2013).

5 C++ // Википедия -- свободная энциклопедия. URL: http://ru.wikipedia.org/wiki/C%2B%2B (дата обращения: 24.05.2013).

6 Джеймс Ф. Куроуз, Кит В. Росс. Компьютерные сети. 2-е изд. -- СПб.: Питер, 2004. -- 765 с.: ил.

7 Сокеты Беркли // Википедия -- свободная энциклопедия. URL: http://ru.wikipedia.org/wiki/%D1%EE%EA%E5%F2%FB_%C1%E5%F0%EA%EB%E8 (дата обращения: 24.05.2013).

8 Winsock // Википедия -- свободная энциклопедия. URL: http://ru.wikipedia.org/wiki/Winsock (дата обращения: 24.05.2013).

9 Qt // Википедия -- свободная энциклопедия. URL: http://ru.wikipedia.org/wiki/Qt (дата обращения: 24.05.2013).

10 Шлее М. Qt4.5. Профессиональное программирование на C++. -- СПб.: БХВ-Петербург, 2010. -- 896 с.: ил.

11 Crypto++ // Wikipedia, the free encyclopedia. URL: http://en.wikipedia.org/wiki/Crypto++ (дата обращения: 24.05.2013).

12 RSA // Википедия -- свободная энциклопедия. URL: http://ru.wikipedia.org/wiki/RSA (дата обращения: 24.05.2013).

13 Advanced Encryption Standard // Википедия -- свободная энциклопедия. URL: http://ru.wikipedia.org/wiki/Advanced_Encryption_Standard (дата обращения: 24.05.2013).

14 ГОСТ 12.0.003-74 «Опасные и вредные производственные факторы» // Бесплатная библиотека стандартов и нормативов www.docload.ru. URL: http://www.docload.ru/Basesdoc/4/4650/index.htm (дата обращения: 24.05.2013).

15 СанПиН 2.2.2/2.4.1340-03 «Гигиенические требования к персональным электронно-вычислительным машинам и организации работы» // Бесплатная библиотека стандартов и нормативов www.docload.ru. URL: http://www.docload.ru/Basesdoc/39/39082/index.htm (дата обращения: 24.05.2013).

16 СанПиН 2.2.4.548-96 «Гигиенические требования к микроклимату производственных помещений» // Бесплатная библиотека стандартов и нормативов www.docload.ru. URL: http://www.docload.ru/Basesdoc/5/5225/index.htm (дата обращения: 24.05.2013).

17 СанПиН 2.2.1/2.1.1.1278-03 «Гигиенические требования к естественному, искусственному и совмещенному освещению жилых и общественных зданий» // Бесплатная библиотека стандартов и нормативов www.docload.ru. URL: http://www.docload.ru/Basesdoc/11/11776/index.htm (дата обращения: 24.05.2013).

18 СН 2.2.4/2.1.8.562-96 «Шум на рабочих местах, в помещениях жилых, общественных зданий и на территории жилой застройки» // БИБЛИОТЕКА ГОСТОВ, СТАНДАРТОВ И НОРМАТИВОВ ИНФОСАЙТ.ру. URL: http://www.infosait.ru/norma_doc/5/5212/index.htm (дата обращения: 24.05.2013).

19 СН 2.2.4/2.1.8.566-96 «Производственная вибрация, вибрация в помещениях жилых и общественных зданий» // Бесплатная библиотека стандартов и нормативов www.docload.ru. URL: http://www.docload.ru/Basesdoc/5/5214/index.htm (дата обращения: 24.05.2013).

Приложение Б Исходный код сервера

Модуль protocol: protocol.h

#ifndef PROTOCOL_H

#define PROTOCOL_H

#include <time.h>

#include <string>

#include <sstream>

#include <fstream>

#include <crypto++/aes.h>

#if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC)

// linux, also other platforms (Hurd etc) that use GLIBC

#include <netinet/in.h>

#include <unistd.h>

#define _OS_LINUX_

#define INVALID_SOCKET 0

typedef int SOCKET;

typedef uint8_t __buf;

#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)

// win32:

#define _WIN32_WINNT 0x0500

#include <windows.h>

#include <winsock2.h>

#define _OS_WINDOWS_

#define sleep(x) Sleep(x*1000)

typedef time_t __time_t;

typedef char __buf;

#endif

using namespace std;

typedef uint16_t PACKTYPE;

typedef uint16_t TAG;

typedef uint16_t STATUS;

typedef uint16_t GROUP_ID;

typedef uint16_t FILE_ID;

typedef uint64_t FSIZE;

typedef uint32_t FPART_NUMBER;

/*

* Константы, характерные для протокола.

*/

// Порт по умолчанию.

#define DEFAULT_SERVER_PORT (uint16_t)6190

// Начало заголовка.

#define HEADER_START (uint8_t)0x3C

// Длина заголовка (байт).

#define HEADER_OFFSET (uint8_t)7

// Максимальный размер пакета (байт).

#define PACK_MAX_SIZE (uint16_t)65535

// Максимальная длина сообщения (байт).

#define MESSAGE_LIMIT (int)65465

// Максимальный размер части файла (байт).

#define MAX_FILE_PART_SIZE (uint16_t)65500

// Размер ключа RSA (бит).

#define RSA_KEY_SIZE (uint16_t)1024

// Размер ключа AES.

#define MESSAGE_KEY_SIZE (uint16_t)CryptoPP::AES::DEFAULT_KEYLENGTH

// Ожидание ответа (сек).

#define WAITING 30

// Тип пакета, определяющий его функциональное назначение.

namespace HEADER_PACKAGE_TYPE

{

// Основные операции.

namespace GENERAL

{

const PACKTYPE PREFIX = 0x0000;

const PACKTYPE ROOT_AUTHORIZATION = 0x0001;

const PACKTYPE CHANGE_ROOT_PASSWORD = 0x0002;

const PACKTYPE RESET_UIN_PASSWORD = 0x0003;

const PACKTYPE SHUTDOWN_SERVER = 0x0004;

const PACKTYPE SERVER_PUBLIC_KEY = 0x0005;

}

// Операции авторизации и управление учетной записью.

namespace AUTHORIZATION

{

const PACKTYPE PREFIX = 0x0100;

const PACKTYPE AUTHORIZATION_UIN = 0x0101;

const PACKTYPE CHANGE_USER_PASSWORD = 0x0102;

const PACKTYPE CHANGE_USER_INFO = 0x0103;

const PACKTYPE GET_USER_INFO = 0x0104;

const PACKTYPE CHANGE_USER_STATUS = 0x0105;

}

// Операции с контакт-листом.

namespace CONTACT_LIST

{

const PACKTYPE PREFIX = 0x0200;

const PACKTYPE GET_GROUP_LIST = 0x0201;

const PACKTYPE GET_CONTACT_LIST = 0x0202;

const PACKTYPE CREATE_USER = 0x0203;

const PACKTYPE DELETE_USER = 0x0204;

const PACKTYPE CREATE_GROUP = 0x0205;

const PACKTYPE ATTACH_TO_GROUP = 0x0206;

const PACKTYPE RENAME_GROUP = 0x0207;

const PACKTYPE DELETE_GROUP = 0x0208;

}

// Отправка сообщений и файлов.

namespace MESSAGES

{

const PACKTYPE PREFIX = 0x0300;

const PACKTYPE GET_MESSAGE_KEY = 0x0301;

const PACKTYPE SEND_MESSAGE = 0x0302;

const PACKTYPE RECV_MESSAGE = 0x0303;

const PACKTYPE GET_UNREAD_MESSAGES = 0x0304;

const PACKTYPE DELETE_UNREAD_MESS = 0x0305;

const PACKTYPE SEND_FILE_REQUEST = 0x0306;

const PACKTYPE SEND_FILE_ACCEPT = 0x0307;

const PACKTYPE SEND_FILE_PART = 0x0308;

const PACKTYPE FILE_SENDER_CHANNEL = 0x0309;

const PACKTYPE FILE_RECEIVER_CHANNEL = 0x030A;

}

// Поддержка канала связи.

const PACKTYPE KEEP_ALIVE = 0xFFFF;

PACKTYPE get_category(const PACKTYPE packtp);

PACKTYPE get_request_code(const PACKTYPE packtp);

}

// Теги, используемые в структурах TLV.

namespace TLVS

{

const TAG ERRORS = 0x0000; // Ошибка, V содержит текстовое

// описание.

const TAG OK = 0x0001; // Удачное завершение операции.

// Не имеет значения (L = 0).

const TAG GROUP_ID = 0x0002; // Идентификатор группы сотрудников,

// V содержит значение типа GROUP_ID.

const TAG GRP_NAME = 0x0003; // Имя группы, V содержит текст.

const TAG PGROUP_ID = 0x0004; // Идентификатор группы-родителя,

// V содержит значение типа GROUP_ID

// (для основных - 0).

const TAG UIN = 0x0005; // Идентификатор сотрудника,

// V содержит текстовое поле

// шириной 8 символов.

const TAG UIN_FROM = 0x0006; // Идентификатор отправителя

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

// V содержит текстовое поле

// шириной 8 символов.

const TAG PASSWORD = 0x0007; // Пароль, V содержит

// зашифрованное по RSA значение.

const TAG NEW_PASSWORD = 0x0008; // Новый пароль - при смене пароля,

// V содержит

// зашифрованное по RSA значение.

const TAG MESSAGE = 0x0009; // Текстовое сообщение, зашифрованное

// симметричным блоковым шифром

// Rijndael.

const TAG DATE_TIME = 0x000A; // Дата и время отправки

// сообщения/файла,

// V содержит строку вида

// "dd.mm.yy HH:MM:SS"

const TAG STATUS = 0x000B; // Статус пользователя, V содержит

// значение типа STATUS.

const TAG STATUS_TEXT = 0x000C; // Статус-текст, V содержит строку.

const TAG SURNAME = 0x000D; // Фамилия сотрудника, V содержит

// строку.

const TAG NAME = 0x000E; // Имя сотрудника, V содержит строку.

const TAG PATRONYMIC = 0x000F; // Отчество сотрудника, V содержит

// строку.

const TAG POST = 0x0010; // Должность сотрудника, V содержит

// строку.

const TAG TELEPHONE = 0x0011; // Телефон сотрудника, V содержит

// строку.

const TAG FILE_ID = 0x0012; // Идентификатор передаваемого файла,

// V содержит значение типа FILE_ID.

const TAG FILE_NAME = 0x0013; // Имя передаваемого файла,

// V содержит строку.

const TAG FILE_SIZE = 0x0014; // Размер передаваемого файла,

// V содержит значение типа FSIZE.

const TAG FILE_PART = 0x0015; // Номер части передаваемого файла,

// V содержит значение типа

// FPART_NUMBER.

const TAG FILE_BODY = 0x0016; // Номер части передаваемого файла,

// V содержит массив байтов.

const TAG FILE_HASH = 0x0017; // MD5 hash передаваемого файла,

// V содержит массив байтов.

const TAG FILE_CANCEL = 0x0018; // Отмена передачи файла.

// Не имеет значения (L = 0).

const TAG PUBLIC_KEY = 0x0019; // Открытый ключ сервера/клиента (RSA)

// V содержит массив байтов.

const TAG MESSAGE_KEY = 0x001A; // Секретный ключ

// для шифрования сообщений (Rijndael),

// V содержит массив байтов.

const TAG IS_GROUP_MESS = 0x001B; // Флаг, сигнализирующий о том, что

// что данное сообщение отправлено

// группе.

}

// Статусы пользователей.

namespace STATUSES

{

const STATUS OFFLINE = 0x0000; // Не в сети.

const STATUS ONLINE = 0x0001; // В сети.

const STATUS BUSY = 0x0002; // Занят.

const STATUS ABSENT = 0x0003; // Отошел.

const STATUS INACCESSIBLE = 0x0004; // Недоступен.

}

// Структура заголовка пакета.

struct HEADER

{

PACKTYPE packtype; // Канал.

uint16_t seq; // Номер пакета.

uint16_t size; // Размер тела пакета (содержимого после заголовка).

};

// Структура TLV.

struct TLV

{

TAG T; // Тег.

uint16_t L; // Длина значения.

uint8_t *V; // Значение.

/*

* Заносит в V значение, хранящееся в массиве v.

*/

void set_V(const uint8_t *v)

{

if (V != NULL) delete [] V;

V = new uint8_t[L];

for (int i = 0; i < L; i++) V[i] = v[i];

}

TLV() { V = NULL; }

TLV(const TLV &s)

{

T = s.T;

L = s.L;

if (s.V != NULL && s.L > 0)

{

V = new uint8_t[L];

for (int i = 0; i < L; i++) V[i] = s.V[i];

}

else V = NULL;

}

~TLV(){ if (V != NULL) delete [] V; }

/*

* Считывает переменную типа T из поля V.

*/

template<typename T>

T getUIntN() const

{

T n = 0;

for (uint8_t i = 0; i < sizeof(T); i++)

n = (n << 8) | V[i];

return n;

}

/*

* Считывает строку из поля V.

*/

string getString() const

{

return string((char*)V, L);

}

};

// Элемент списка контактов.

struct Entity

{

string Name; // Имя элемента.

GROUP_ID ParentGroupID; // ID группы-родителя.

void *reference; // Указатель на дополнительные данные.

Entity()

{

Name = "";

ParentGroupID = 0;

reference = NULL;

}

};

// Группа.

struct Group : public Entity

{

GROUP_ID GroupID; // ID группы.

Group() { GroupID = 0; }

};

// Сотрудник (контакт).

struct Contact : public Entity

{

string UIN; // Уникальный идентификатор сотрудника.

string Surname; // Фамилия.

string Patronymic; // Отчество.

string Post; // Должность.

string Telephone; // Телефон.

STATUS Status; // Статус.

string StatusText; // Статус-текст.

string Password; // Пароль учетной записи.

SOCKET sock;

Contact()

{

UIN = Surname = Name = Patronymic = Telephone = "";

sock = INVALID_SOCKET;

Status = STATUSES::OFFLINE;

StatusText.clear();

}

};

// Сообщение.

struct AbstractMessage

{

string UIN_to; // UIN получателя.

string UIN_from; // UIN отправителя.

string DateTime; // Дата и время отправки в формате "dd.mm.yy HH:MM:SS".

/*

* Установка времени отправки.

*/

void set_current_time()

{

char s[20];

time_t ct = time(NULL);

struct tm *lct = localtime(&ct);

strftime(s, 20, "%d.%m.%y %H:%M:%S", lct);

DateTime = string(s);

}

};

// Текстовое сообщение.

struct Message : public AbstractMessage

{

GROUP_ID Group_to; // ID группы-получателя (при передаче сообщения группе).

string Text; // Текст сообщения.

bool IsGroupMessage;

void clear()

{

UIN_to = UIN_from = DateTime = Text = "";

Group_to = 0;

IsGroupMessage = false;

}

};

// Передаваемый файл.

struct File : public AbstractMessage

{

FILE_ID FileID; // Идентификатор передаваемого файла.

string FileName; // Имя файла.

FSIZE FileSize; // Размер файла.

bool accepted; // Флаг подтверждения приема.

bool canceled; // Флаг отмены передачи.

bool finished; // Флаг завершения передачи.

void *reference; // Указатель на дополнительные данные.

File()

{

accepted = false;

canceled = false;

finished = false;

FileID = 0;

FileSize = 0;

}

};

// Временный буфер для хранения ранее прочитанной части пакета.

struct TemporaryBuffer

{

SOCKET sock; // Сокет, с которого считывается пакет.

uint8_t buf[PACK_MAX_SIZE]; // Буфер, содержащий часть пакета.

uint16_t offset; // Отступ внутри буфера от его начала.

TemporaryBuffer()

{

sock = INVALID_SOCKET;

offset = 0;

}

/*

* Разбирает заголовок считываемого пакета.

*/

bool decode_header(HEADER &h)

{

if (buf[0] != HEADER_START) return false;

h.packtype = buf[1];

h.packtype = (h.packtype << 8) | buf[2];

h.seq = buf[3];

h.seq = (h.seq << 8) | buf[4];

h.size = buf[5];

h.size = (h.size << 8) | buf[6];

return true;

}

};

/*

* Сбрасывает номер пакета до 1.

*/

void header_datagram_reset();

/*

* Печатает байт в СС HEX.

*/

string byteToString16(uint8_t val);

// Сформированный пакет.

class Package

{

uint8_t buf[PACK_MAX_SIZE]; // Буфер, содержащий пакет.

uint16_t offset; // Отступ внутри буфера от его начала.

uint16_t length; // Размер тела пакета.

/* Считывает переменную с текущего места буфера, увеличивая отступ

* offset на ее размер

*/

template<typename T>

T getUIntN()

{

T n = 0;

for (uint8_t i = 0; i < sizeof(T); i++)

n = (n << 8) | buf[offset++];

return n;

}

/* Записывает переменную val в текущее место буфера, увеличивая

* длину length на ее размер

*/

template<typename T>

void setUIntN(const T val)

{

for (uint8_t i = 0; i < sizeof(T); i++)

buf[HEADER_OFFSET + length++] =

(val >> 8*(sizeof(T) - 1 - i)) & 0xff;

}

public:

Package() { clear(); }

/*

* Сбрасывает отступ внутри буфера.

*/

void clearOffset() { offset = HEADER_OFFSET; }

/*

* Сбрасывает отступ и длину пакета.

*/

void clear()

{

offset = HEADER_OFFSET;

length = 0;

}

/*

* Устанавливает длину пакета.

*/

void setLength(uint16_t l);

/*

* Создает заголовок пакета, при этом номер пакета устанавливается

* равным текущему номеру, увеличенному на 1.

*/

void generate_header(const PACKTYPE packtype);

/*

* Создает заголовок пакета, при явном указании номера пакета.

*/

void generate_header(const PACKTYPE packtype,

const uint16_t HEADER_datagram);

/*

* Разбирает заголовок считываемого пакета, записывает его в h и

* возвращает

* true в случае успеха, возвращает false если заголовок испорчен.

*/

bool decode_header(HEADER &h);

/*

* Возвращает указатель на буфер пакета.

*/

char *buffer();

/*

* Возвращает номер пакета, содержащийся в заголовке.

*/

uint16_t getPackSeqNumber();

/*

* Устанавливает номер пакета в его заголовок.

*/

void setPackSeqNumber(uint16_t seqNumber);

/*

* Возвращает длину пакета.

*/

uint16_t getPackLength();

/*

* Записывает пустой TLV (L = 0) с указанным тегом T в текущее место

* буфера.

*/

void write_TLV(const TAG T);

/*

* Записывает строковый TLV с указанным тегом T и значением-строкой V

* в текущее место буфера.

*/

void write_TLV(const TAG T, const string V);

/*

* Записывает TLV с указанным тегом T, длиной массива L

* и значением-массивом V в текущее место буфера.

*/

void write_TLV(const TAG T, const uint16_t L, const uint8_t* V);

/*

* Записывает TLV с указанным тегом T и значением-переменной V

* в текущее место буфера.

*/

template<typename TYPE>

void write_TLV(const TAG T, const TYPE V)

{

setUIntN(T);

setUIntN((uint16_t)sizeof(TYPE));

setUIntN(V);

}

/*

* Считывает TLV из буфера с требуемым тегом tag и помещает ее в tlv;

* возвращает true, если TLV найдена и успешно разобрана на составляющие,

* в противном случае возвращает false.

*/

bool decode_TLV(const TAG tag, TLV &tlv);

/* Cчитывает пакет во временный буфер tbuf и возвращает

* 0, если пакет не дошел полностью,

* -1, если соединение разорвано,

* -2, если заголовок пакета испорчен,

* размер пакета, если пакет дошел полностью

* (при этом пакет переписывается из временного буфера в buf,

* а временный буфер сбрасывается).

*/

int read_package(TemporaryBuffer &tbuf);

/*

* Отправляет пакет получателю sock, с указанием флагов отправки.

* Возвращает количество отправленных байт пакета либо

* -1, если отправить не удалось.

*/

int send_package(SOCKET sock, int flags);

/*

* Записывает информацию о группе в буфер.

*/

void write_group_info(const Group &p);

/*

* Считывает информацию о группе из буфера, возвращает true,

* если присутствуют все необходимые поля, в противном случае - false.

*/

bool read_group_info(Group &p);

/*

* Записывает базовые сведения о пользователе в буфер.

*/

void write_base_user_info(const Contact &p);

/*

* Записывает базовые сведения о пользователе, а также статус и

* статус-текст, в буфер.

*/

void write_user_info_with_status(const Contact &p);

/*

* Считывает базовые сведения о пользователе из буфера, возвращает true,

* если присутствуют все необходимые поля, в противном случае - false.

*/

bool read_base_user_info(Contact &p);

/*

* Считывает базовые сведения о пользователе, а также статус и

* статус-текст, из буфера, возвращает true,

* если присутствуют все необходимые поля, в противном случае - false.

*/

bool read_user_info_with_status(Contact &p);

/*

* Записывает текстовое сообщение в буфер.

*/

void write_unread_messages(const Message &p);

/*

* Считывает текстовое сообщение из буфера, возвращает true,

* если присутствуют все необходимые поля, в противном случае - false.

*/

bool read_unread_messages(Message &p);

/*

* Записывает тело пакета в файл с указанием его длины.

*/

void write_body_to_file(ofstream& out);

/*

* Считывает тело пакета из файл с учетом его длины, указанной перед

* телом.

*/

void read_body_from_file(ifstream& in);

/*

* Печатает содержимое буфера, содержащего пакет, в СС HEX.

*/

string print_package();

};

#endif // PROTOCOL_H

Модуль protocol: protocol.cpp

#include "protocol.h"

uint16_t HEADER_datagram = 1;

PACKTYPE HEADER_PACKAGE_TYPE::get_category(const PACKTYPE packtp)

{

return packtp & 0xFF00;

}

PACKTYPE HEADER_PACKAGE_TYPE::get_request_code(const PACKTYPE packtp)

{

return packtp & 0x00FF;

}

void header_datagram_reset()

{

HEADER_datagram = 1;

}

string byteToString16(uint8_t val)

{

ostringstream oss;

oss << std::hex << (int)val << std::dec;

return oss.str();

}

void Package::setLength(uint16_t l) { length = l;}

void Package::generate_header(const PACKTYPE packtype)

{

buf[0] = HEADER_START;

buf[1] = (packtype >> 8) & 0xff;

buf[2] = packtype & 0xff;

buf[3] = (HEADER_datagram >> 8) & 0xff;

buf[4] = HEADER_datagram & 0xff;

buf[5] = (length >> 8) & 0xff;

buf[6] = length & 0xff;

if (HEADER_datagram == SHRT_MAX - 1) HEADER_datagram = 1;

else HEADER_datagram++;

}

void Package::generate_header(const PACKTYPE packtype,

const uint16_t HEADER_datagram)

{

buf[0] = HEADER_START;

buf[1] = (packtype >> 8) & 0xff;

buf[2] = packtype & 0xff;

buf[3] = (HEADER_datagram >> 8) & 0xff;

buf[4] = HEADER_datagram & 0xff;

buf[5] = (length >> 8) & 0xff;

buf[6] = length & 0xff;

}

bool Package::decode_header(HEADER &h)

{

if (buf[0] != HEADER_START) return false;

uint16_t _offset = offset;

offset = 1;

h.packtype = getUIntN<PACKTYPE>();

h.seq = getUIntN<uint16_t>();

h.size = getUIntN<uint16_t>();

offset = _offset;

return true;

}

char* Package::buffer()

{

return (char*)buf;

}

uint16_t Package::getPackSeqNumber()

{

uint16_t _offset = offset;

offset = 3;

uint16_t seq = getUIntN<uint16_t>();

offset = _offset;

return seq;

}

void Package::setPackSeqNumber(uint16_t seqNumber)

{

buf[3] = (seqNumber >> 8) & 0xff;

buf[4] = seqNumber & 0xff;

}

uint16_t Package::getPackLength()

{

return length + HEADER_OFFSET;

}

void Package::write_TLV(const TAG T)

{

setUIntN(T);

setUIntN((uint16_t)0x0);

}

void Package::write_TLV(const TAG T, const string V)

{

write_TLV(T, V.length(), (uint8_t*)V.c_str());

}

void Package::write_TLV(const TAG T, const uint16_t L, const uint8_t* V)

{

setUIntN(T);

setUIntN(L);

for (uint16_t i = 0; i < L; i++)

setUIntN(V[i]);

}

bool Package::decode_TLV(const TAG tag, TLV &tlv)

{

TAG t;

uint16_t l;

clearOffset();

while ((length + HEADER_OFFSET - offset) >= (int)sizeof(uint16_t)*2)

{

t = getUIntN<TAG>();

l = getUIntN<uint16_t>();

if (t == tag)

{

if ((length + HEADER_OFFSET - offset) < l)

return false;

tlv.T = t;

tlv.L = l;

tlv.set_V(buf + offset);

return true;

}

else offset += l;

}

return false;

}

int Package::read_package(TemporaryBuffer &tbuf)

{

int bytes;

if (tbuf.offset < HEADER_OFFSET)

{

bytes = recv(tbuf.sock, (__buf*)(tbuf.buf + tbuf.offset),

HEADER_OFFSET - tbuf.offset, 0);

if (bytes > 0) tbuf.offset += bytes;

}

if (tbuf.offset < HEADER_OFFSET) return 0;

HEADER h;

if (!tbuf.decode_header(h))

{

tbuf.offset = 0;

return -2;

}

bytes = recv(tbuf.sock, (__buf*)(tbuf.buf + tbuf.offset),

h.size - (tbuf.offset - HEADER_OFFSET), 0);

if (bytes > 0) tbuf.offset += bytes;

if (tbuf.offset - HEADER_OFFSET < h.size) return 0;

memcpy(buf, tbuf.buf, tbuf.offset);

tbuf.offset = 0;

offset = HEADER_OFFSET;

length = h.size;

return h.size + HEADER_OFFSET;

}

int Package::send_package(SOCKET sock, int flags)

{

int total = 0;

int n = 0;

uint8_t i = 0;

while(total < length + HEADER_OFFSET)

{

n = send(sock, (__buf*)(buf + total), length + HEADER_OFFSET - total,

flags);

if (n == 0) return -1;

if(n < 0)

{

if (i == WAITING) return -1;

else

{

sleep(1);

i++;

continue;

}

}

total += n;

}

return total;

}

void Package::write_group_info(const Group &p)

{

write_TLV(TLVS::GROUP_ID, p.GroupID);

write_TLV(TLVS::GRP_NAME, p.Name);

write_TLV(TLVS::PGROUP_ID, p.ParentGroupID);

}

bool Package::read_group_info(Group &p)

{

TLV tlv;

if (decode_TLV(TLVS::GROUP_ID, tlv))

p.GroupID = tlv.getUIntN<GROUP_ID>();

else return false;

if (decode_TLV(TLVS::GRP_NAME, tlv))

p.Name = tlv.getString();

else return false;

if (decode_TLV(TLVS::PGROUP_ID, tlv))

p.ParentGroupID = tlv.getUIntN<GROUP_ID>();

else return false;

return true;

}

void Package::write_base_user_info(const Contact &p)

{

write_TLV(TLVS::UIN, p.UIN);

write_TLV(TLVS::PGROUP_ID, p.ParentGroupID);

write_TLV(TLVS::SURNAME, p.Surname);

write_TLV(TLVS::NAME, p.Name);

write_TLV(TLVS::PATRONYMIC, p.Patronymic);

write_TLV(TLVS::POST, p.Post);

write_TLV(TLVS::TELEPHONE, p.Telephone);

}

void Package::write_user_info_with_status(const Contact &p)

{

write_base_user_info(p);

write_TLV(TLVS::STATUS, p.Status);

write_TLV(TLVS::STATUS_TEXT, p.StatusText);

}

bool Package::read_base_user_info(Contact &p)

{

TLV tlv;

if (decode_TLV(TLVS::UIN, tlv))

p.UIN = tlv.getString();

else return false;

if (decode_TLV(TLVS::PGROUP_ID, tlv))

p.ParentGroupID = tlv.getUIntN<GROUP_ID>();

else return false;

if (decode_TLV(TLVS::SURNAME, tlv))

p.Surname = tlv.getString();

else return false;

if (decode_TLV(TLVS::NAME, tlv))

p.Name = tlv.getString();

else return false;

if (decode_TLV(TLVS::PATRONYMIC, tlv))

p.Patronymic = tlv.getString();

else return false;

if (decode_TLV(TLVS::POST, tlv))

p.Post = tlv.getString();

else return false;

if (decode_TLV(TLVS::TELEPHONE, tlv))

p.Telephone = tlv.getString();

else return false;

return true;

}

bool Package::read_user_info_with_status(Contact &p)

{

if (!read_base_user_info(p)) return false;

TLV tlv;

if (decode_TLV(TLVS::STATUS, tlv))

p.Status = tlv.getUIntN<STATUS>();

else return false;

if (decode_TLV(TLVS::STATUS_TEXT, tlv))

p.StatusText = tlv.getString();

else return false;

return true;

}

void Package::write_unread_messages(const Message &p)

{

if (p.IsGroupMessage)

write_TLV(TLVS::GROUP_ID, p.Group_to);

else

write_TLV(TLVS::UIN, p.UIN_to);

write_TLV(TLVS::UIN_FROM, p.UIN_from);

write_TLV(TLVS::DATE_TIME, p.DateTime);

write_TLV(TLVS::MESSAGE, p.Text);

}

bool Package::read_unread_messages(Message &p)

{

TLV tlv;

p.clear();

if (decode_TLV(TLVS::IS_GROUP_MESS, tlv))

{

p.IsGroupMessage = tlv.getUIntN<bool>();

if (decode_TLV(TLVS::UIN, tlv))

p.UIN_to = tlv.getString();

else return false;

if (p.IsGroupMessage)

{

if (decode_TLV(TLVS::GROUP_ID, tlv))

p.Group_to = tlv.getUIntN<GROUP_ID>();

else return false;

}

}

else

{

if (decode_TLV(TLVS::UIN, tlv))

{

p.UIN_to = tlv.getString();

p.IsGroupMessage = false;

}

else if (decode_TLV(TLVS::GROUP_ID, tlv))

{

p.Group_to = tlv.getUIntN<GROUP_ID>();

p.IsGroupMessage = true;

}

else return false;

}

if (decode_TLV(TLVS::UIN_FROM, tlv))

p.UIN_from = tlv.getString();

else return false;

if (decode_TLV(TLVS::DATE_TIME, tlv))

p.DateTime = tlv.getString();

else return false;

if (decode_TLV(TLVS::MESSAGE, tlv))

p.Text = tlv.getString();

else return false;

return true;

}

void Package::write_body_to_file(ofstream &out)

{

out.write(reinterpret_cast<char*>(&length), sizeof(length));

out.write(reinterpret_cast<char*>(buf + HEADER_OFFSET), length);

}

void Package::read_body_from_file(ifstream& in)

{

in.read(reinterpret_cast<char*>(&length), sizeof(length));

in.read(reinterpret_cast<char*>(buf + HEADER_OFFSET), length);

offset = HEADER_OFFSET;

}

string Package::print_package()

{

string str;

for (int i = 0; i < length + HEADER_OFFSET; i++)

str += ((buf[i] < 16) ? string("0") : string()) +

byteToString16(buf[i]) + string(" ");

return str;

}

Приложение В Исходный код администрирующего клиента

Модуль widget: widget.cpp

int Widget::read_from_server(Package &pack)

{

if (!sock->isOpen())

{

temp_buf.offset = 0;

disconnect_form_server();

QMessageBox::critical(this, trUtf8("Ошибка"),

trUtf8("Соединение не установлено!"));

return -1;

}

int bytes;

if (temp_buf.offset < HEADER_OFFSET)

{

bytes = sock->read((char*)(temp_buf.buf + temp_buf.offset),

HEADER_OFFSET - temp_buf.offset);

if (bytes > 0) temp_buf.offset += bytes;

}

if (temp_buf.offset < HEADER_OFFSET) return 0;

HEADER h;

if (!temp_buf.decode_header(h))

{

temp_buf.offset = 0;

disconnect_form_server();

QMessageBox::critical(this, trUtf8("Ошибка"),

trUtf8("Заголовок пакета испорчен!"));

return -1;

}

bytes = sock->read((char*)(temp_buf.buf + temp_buf.offset),

h.size - (temp_buf.offset - HEADER_OFFSET));

if (bytes > 0) temp_buf.offset += bytes;

if (temp_buf.offset - HEADER_OFFSET < h.size) return 0;

pack.clear();

memcpy(pack.buffer(), temp_buf.buf, temp_buf.offset);

temp_buf.offset = 0;

pack.setLength(h.size);

writeToHistory(pack, true);

return h.size + HEADER_OFFSET;

}

int Widget::send_to_server(Package &pack, string err)

{

if (!sock->isOpen()) return -1;

int cnt;

if ((cnt = sock->write(pack.buffer(), pack.getPackLength())) !=

pack.getPackLength())

{

disconnect_form_server();

if (!err.empty())

QMessageBox::critical(this, trUtf8("Ошибка"),

trUtf8(err.c_str()));

return -1;

}

writeToHistory(pack, false);

return cnt;

}

void Widget::slot_login(string pass)

{

HEADER h;

TLV tlv;

int cnt, bytes_read;

while (sock->bytesAvailable() > 0 || sock->waitForReadyRead())

{

bytes_read = read_from_server(inpack);

if (bytes_read < 0) return;

if (bytes_read > 0) break;

}

if (bytes_read == 0)

{

disconnect_form_server();

QMessageBox::critical(this, trUtf8("Ошибка"),

trUtf8("Сервер не высылает ключ!"));

return;

}

if (!inpack.decode_header(h))

{

disconnect_form_server();

QMessageBox::critical(this, trUtf8("Ошибка"),

trUtf8("Заголовок испорчен. "

"Соединение сброшено!"));

return;

}

if (h.packtype != HEADER_PACKAGE_TYPE::GENERAL::SERVER_PUBLIC_KEY)

{

disconnect_form_server();

QMessageBox::critical(this, trUtf8("Ошибка"),

trUtf8("Неверный тип пакета. "

"Соединение сброшено!"));

return;

}

if (!inpack.decode_TLV(TLVS::PUBLIC_KEY, tlv))

{

disconnect_form_server();

QMessageBox::critical(this, trUtf8("Авторизация администратора"),

trUtf8("Не обнаружено поле ключа!"));

return;

}

conn_wgt->pb_inc();

ByteQueue queue;

StringSource str_key(tlv.getString(), true /*pumpAll*/);

str_key.TransferTo(queue);

queue.MessageEnd();

try

{

serverPublicKey->Load(queue);

}

catch (BERDecodeErr e)

{

disconnect_form_server();

QMessageBox::critical(this, trUtf8("Ошибка"),

trUtf8("Невозможно декодировать ключ сервера: ") +

trUtf8(e.what()));

return;

}

if(!serverPublicKey->Validate(rng, 3))

{

disconnect_form_server();

QMessageBox::critical(this, trUtf8("Ошибка"),

trUtf8("Открытый ключ сервера испорчен!"));

return;

}

string cipher;

RSAES_OAEP_SHA_Encryptor e(*serverPublicKey);

StringSource(pass, true, new PK_EncryptorFilter(rng, e,

new StringSink(cipher)));

outpack.clear();

outpack.write_TLV(TLVS::PASSWORD, cipher);

outpack.generate_header(HEADER_PACKAGE_TYPE::GENERAL::ROOT_AUTHORIZATION);

cnt = send_to_server(outpack, "Ключ не может быть отправлен!");

if (cnt < 0) return;

bytes_read = 0;

while (sock->bytesAvailable() > 0 || sock->waitForReadyRead())

{

bytes_read = read_from_server(inpack);

if (bytes_read < 0) return;

if (bytes_read > 0) break;

}

if (bytes_read == 0)

{

disconnect_form_server();

QMessageBox::critical(this, trUtf8("Ошибка"),

trUtf8("Сервер не отвечает на авторизацию!"));


Подобные документы

  • Создание клиент-серверного приложения "Чат" с помощью среды визуальной разработки приложений Borland C++ Builder версии 6. Описание функциональности приложения: наличие клиент-серверной архитектуры, обмен короткими сообщениями, а также передача файлов.

    курсовая работа [302,0 K], добавлен 30.01.2012

  • Изучение истории достижений корпорации Oracle. Разработка клиент-серверного приложения на языке Delphi XE, реализующего возможность управления персоналом на предприятии. Основные структуры данных. Создание инструкции работы с приложением "Отдел кадров".

    дипломная работа [974,7 K], добавлен 08.06.2013

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

    курсовая работа [191,5 K], добавлен 07.01.2015

  • Многоуровневые архитектуры клиент–сервер. Диаграммы классов, реализующих уровни презентации, бизнес–логики и базы данных приложения. Словесное описание процесса выполнения транзакций. Создание, изменение и удаление хранимых процедур, их выполнение.

    курсовая работа [3,4 M], добавлен 23.03.2013

  • Разработка компьютерной сети. Спецификация и расчет себестоимости спроектированной сети. Выбор инструментальных средств для реализации разрабатываемого клиент-серверного приложения. Описание логической структуры программного продукта, основные алгоритмы.

    курсовая работа [942,1 K], добавлен 19.03.2012

  • Разработка конфигурации службы. Исследование вычислительной эффективности алгоритма оптимизации. Программная реализация клиент-серверного приложения. Алгоритм решения непрерывной задачи загрузки рюкзака. Подключение веб-сервиса к клиентскому приложению.

    курсовая работа [1,4 M], добавлен 21.01.2017

  • Разработка клиент-серверного приложения, позволяющего взаимодействовать друг с другом с использованием доступа к базам данных. Проектирование связи сервера с базой данных с помощью технологии ODBC. Разработка интерфейса программы, ее тестирование.

    курсовая работа [352,0 K], добавлен 24.08.2016

  • Основные концепции разработки приложения в трёхуровневой архитектуре. Проектное решение, реализующее модель реляционной БД. Спецификация на разработку интерфейса. Описание выполнения транзакций прибытия и убытия судна. Инсталляционные файлы приложения.

    курсовая работа [4,0 M], добавлен 26.12.2011

  • Создание клиент-серверного приложения на основе технологии CORBA. Проектирование многоуровневой системы, в которой клиент при помощи банкомата выполняет необходимые операции. Способы реализации серверов в разных каналах для ускорения обработки данных.

    лабораторная работа [1,1 M], добавлен 08.06.2009

  • Характеристика разновидностей программной реализации чатов. Разработка программы клиент-серверного чата с возможность общения в локальной сети нескольких человек одновременно. Протокол взаимодействия клиента и сервера. Порядок работы с программой.

    курсовая работа [530,7 K], добавлен 25.04.2015

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.