Изучение объектно-ориентированного языка программирования Java и создание программного кода на языке Java

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

2015-09-08

2.9 MB

11 чел.


Поделитесь работой в социальных сетях

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


СОДЕРЖАНИЕ

Введение 5

1  ОПИСАНИЕ СРЕДЫ РАЗРАБОТКИ 7

1.1  Интегрированная среда разработки Eclipse 7

1.2 Описание языка JAVA 11

2  ОПИСАНИЕ КЛАССОВ и методов , ИСПОЛЬЗОВАННЫХ В  ПРОГРАММЕ  16

2.1 Класс ChatMessage 16

2.2 Класс Server 16

2.3 Класс Client 16

2.4 Класс GUI 17

3  РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ …….…20

3.1 Запуск сервера 20

2.3 Запуск клиентского приложения 20

ЗАКЛЮЧЕНИЕ 24

СПИСОК ИСПОЛЬЗУЕМЫХ ИСТОЧНИКОВ 25

ПРИЛОЖЕНИЯ А: ЛИСТИНГ ОСНОВНЫХ КЛАССОВ ПРИЛОЖЕНИЯ 26

ПРИЛОЖЕНИЯ Б: ДОКУМЕНТАЦИЯ JAVA 53

ВВЕДЕНИЕ

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

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

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

Java – объектно-ориентированный язык, удобный и надёжный в эксплуатации благодаря таким своим достоинствам, как многозадачность, поддержка протоколов Internet и многоплатформенность. Java – это интерпретируемый язык, и каждая Java-программа компилируется для гипотетической машины, называемой Виртуальная Машина Java. Результатом такой компиляции является байт-код Java, который в свою очередь может выполняться на любой операционной системе при условии наличия там системы времени выполнения Java, которая интерпретирует байт-код в реальный машинный код конкретной системы.

Задачами курсовой работы является изучение объектно-ориентированного языка программирования Java  и создание программного кода на языке Java [1].

  1.  ОПИСАНИЕ СРЕДЫ РАЗРАБОТКИ

1.1 Интегрированная среда разработки Eclipse

1.1.1 Описание среды разработки Eclipse. Для разработки на языке Java существует  большое  количество интегрированных сред разработки. Примером являются:

1. Eclipse.

2. Netbeans.

3. IntelliJ IDEA.

4. Jcreator.

Для разработки курсовой работы была выбрана интегрированная среда разработки Eclipse.

Eclipse – один из лучших инструментов Java, созданных за последние годы. SDK Eclipse представляет собой интегрированную среду разработки (IDE, Integrated Development Environment) с открытым исходным кодом. Среда разработки Eclipse является модульной средой разработки на основе программного ядра и интерфейсов для написания и подключения дополнительных модулей (плагинов, plugin). Таким образом, среда Eclipse может быть использована не только для написания приложений на языке Java, но также и для других целей, в зависимости от установленных плагинов.

Основные инструментальные средства Eclipse Java включают в себя: редактор исходного кода (создание и редактирование исходного текста программ), средства отладки и интеграции с Ant.

При первоначальном знакомстве со средой IDE Eclipse она может показаться несколько сложной для неподготовленного пользователя. Для того чтобы понять основы работы с системой, нужно уяснить себе основные концепции среды: рабочее пространство, инструменты, компоновки, редакторы и представления.

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

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

К инструментам (workbench) относится набор соответствующих редакторов и представлений, размещенных в рабочей области Eclipse (рисунок 6). Для конкретной задачи определенный набор редакторов и представлений называют перспективой или компоновкой.

Компоновка (perspective) – это набор представлений и редакторов, расположенных в том порядке, который вам требуется. В каждой компоновке присутствует свой набор инструментов, некоторые компоновки могут иметь общие наборы инструментов. В определенный момент времени активной может быть только одна компоновка. Переключение между различными компоновками осуществляется нажатием клавиш «Ctrl+F8».

Используя компоновки, вы можете настроить свое рабочее пространство под определенный тип выполняемой задачи. В пособии будут использоваться компоновки, связанные в основном с программированием на Java, такие, как: Debug, Java Browsing, Java.

В Eclipse имеется также возможность создавать свои компоновки.

Открыть компоновку можно командой Window / Open Perspective.

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

Представления по существу являются дополнениями к редакторам, где выводится информация сопроводительного или дополнительного характера, как правило, о файле, находящемся в редакторе. Открыть представления можно командой Window / Show View.

Проект (project) представляет собой набор файлов приложения и сопутствующих дополнений. При работе с Java используются в основном файлы, имеющие следующие расширения: .java, .jsp, .xml.

Дополнением (plug-in) называют приложение, которое дополнительно может быть установлено в Eclipse. Примером дополнения может выступать JDT.

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

  1.  Системные требования. Eclipse разработана для широкого круга операционных систем, таких как Linux, Microsoft Windows и Mac OS. Для ее запуска требуется JVM (Java Virtual Machine) – виртуальная Java-машина, а также JDK(Java Development Kit)  –  набор для Java-разработки [2].

Таблица 1 – Системные требования к среде разработки Eclipse

Требования

Минимальное значение

Рекомендуемое значение

Версия Java

1.4.0

1.6.0 и выше

Оперативная память

128 Мб

1 Гб и выше

Свободное пространство на ЖД

300 Мб

1 ГБ и более

Процессор

533 МГц

1,5 ГГц и более

1.1.3 Установка среды разработки Eclipse. На первом этапе происходит установка нужной версии библиотек поддержки Java. Ее можно  найти на eclipse.org.

После установки  Java VM, переходим к установке Eclipse. Переходим на страницу для  скачивания файлов Eclipse (http://www.eclipse.org/downloads/) ,затем выбираем последнюю готовую (release) версию для нашей платформы.

         Поскольку Eclipse построен на Java, программное обеспечение требует для выполнения Java Development Kit (JDK) – бесплатно распространяемый компанией Oracle Corporation (ранее Sun Microsystems) комплект разработчика приложений на языке Java, включающий в себя компилятор Java (javac), стандартные библиотеки классов Java, примеры, документацию, различные утилиты и исполнительную систему Java (JRE). В состав JDK не входит интегрированная среда разработки на Java, поэтому разработчик, использующий только JDK, вынужден использовать внешний текстовый редактор и компилировать свои программы, используя утилиты командной строки.

 

Рисунок 1  Окно установки JDK

При первом запуске загрузчика Eclipse перед появлением самой среды выполняется ряд завершающих установочных шагов (например, создание директории workspace для хранения файлов проектов) [3].

 Рисунок 1.2 – Окно запуска Eclipse

1.2 Описание языка Java

Объектно-ориентированный язык Java,разработанный в Sun Microsystems, предназначен для создания переносимых на различные платформы и операционные системы программ. Язык Java нашел широкое применение в Интернет-приложениях, добавив на статические и клиентские Web-страницы динамическую графику, улучшив интерфейсы и реализовав вычислительные возможности.

1.2.2 Функциональные возможности языка JAVA. Кратко перечислим основные возможности языка Java.

Компоненты в окне аплета. В окне аплета можно размешать следующие элементы управления Windows:

кнопки;

переключатели с независимой и зависимой фиксацией;

статические текстовые поля;

однострочные и многострочные поля редактирования текста;

списки;

полосы прокрутки.

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

  1.   Панели. В окне аплета можно создать несколько панелей на основе класса Panel. При помощи этого можно организовать пользовательский интерфейс, ввиду того, что объекты панели обладают уникальными свойствами. Панель может содержать компоненты и другие панели, для каждой панели можно определить свой режим размещения компонент.
  2.   Окна. Аплет Java может работать не только с собственным окном, но также может создавать обычные перекрывающиеся окна, которые могут иметь меню, быть перемещаемыми и т.д. Можно создать два класса окон: фреймы (обычные окна) и диалоговые окна.
  3.   Рисование в окне аплета. Аплет выполняет рисование в своём окне, используя методы класса Graphics, в котором полностью инкапсулированы особенности аппаратной платформы. Для окна аплета создаётся объект класса Graphics, ссылка на который передаётся методу Paint.
  4.   Растровые изображения. Рисование простых и анимированных изображений является одним из самых распространённых применений аплетов. Библиотеки классов Java содержат простые в использовании средства, предназначенные для работы с растровыми изображениями форматов GIF и JPEG: загрузки, масштабирования, создания на их базе анимационных изображений.
  5.   Анимация. Аплеты Java предоставляют пользователю возможность отображения небольших анимационных и видероликов на страницах Web – сервера. Для этого необходимо подготовить и разместить в каталогах Web сервера файлы отдельных кадров фильма в формате GIF или JPEG. Аплет Java загрузит эти изображения, после чего начнёт их поочерёдное отображение в цикле. Этот цикл должен выполняться в отдельной задаче.
  6.   Звук. Звуковые возможности аплетов Java ограничиваются воспроизведением звуковых клипов, записанных только в файлах формата AU (фирма Sun). Однако в Internet существует конвертеры для данного формата (например, freeware программа GoldWave, доступная по адресу ftp.winsite.com).
  7.   Взаимодействие между аплетами. Аплеты, расположенные в одном и том же документе HTML могут взаимодействовать между собой, используя ссылки на другие аплеты, которые можно получить через интерфейс AppletContext.
  8.   Обработка событий. Когда пользователь выполняет операции с мышью или клавиатурой в окне аплета, возникают события, которые передаются соответствующим методам класса Applet. Переопределяя эти методы, можно организовать обработку событий, возникающих в процессе взаимодействия с  мышью и клавиатурой.
  9.   Реализация мультизадачности. Для создания мультизадачных приложений Java необходимо использовать класс java.lang.Thread. В том классе определены все методы, необходимые для создания задач, управления их состоянием и синхронизации.
  10.  Работа с файлами. Хотя аплеты не имеют доступа к локальным файлам, они могут обращаться к файлам, находящимся в каталогах WWW – сервера. Библиотека классов языка Java содержит многочисленные средства, предназначенные для работы с файлами. Все взаимодействие происходит через потоки следующих видов:

стандартные потоки ввода и вывода,

потоки, связанные с локальными файлами,

потоки, связанные с файлами  в оперативной памяти,

потоки, связанные с удалёнными файлами.

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

  1.  Характерные особенности языка Java.
  2.   Простой. Данная система легко программируется и представляет собой очищенный вариант синтаксиса языка C++.Объектно-ориентированный. Это метод программирования, в центре внимания которого находятся данные (т.е. объекты) и средства доступа к ним.
  3.   Распределенный. Он обладает большой библиотекой программ для передачи данных на основе таких протоколов TCP/IP(Transmission Control Protocol/Internet Protocol),как HTTP(Hypertaxt Transfer Protocol) или FTP(File Transfer Protocol).
  4.   Надежный. Язык Java предназначен для создания программ, которые должны надежно работать в любых ситуациях. Основное внимание уделяется раннему обнаружению возможных ошибок, динамической проверке, исключению ситуаций, подверженных ошибкам.
  5.  Безопасный. Язык Java предназначен для использования в сетевой или распределенной среде.
  6.  Не зависящий от архитектуры. Компилятор генерирует объектный файл, формат которого не зависит от архитектуры компьютера, – скомпилированная программа может выполняться на любых процессорах под управлением системы выполнения программ языка Java.
  7.  Интерпретируемый. Интерпретатор языка Java может пересылать на любую машину и выполнять байт-код непосредственно на ней.
  8.  Высокопроизводительный. Байт-коды можно во время выполнения транслировать в машинные коды для конкретного процессора, на котором выполняется данное приложение [4].

  1.  ОПИСАНИЕ КЛАССОВ И МЕТОДОВ ,           ИСПОЛЬЗОВАННЫХ В ПРОГРАММЕ

2.1 Класс ChatMessage

При установлении соединения через TCP фактически по сети передаются байты.

Когда мы работаем между двумя приложениями Java, если оба имеют доступ к тем же кодам, пересылаются объекты  между двумя приложениями. Serializable (cериализация) –  это процесс сохранения состояния объекта в последовательность байт; Deserializable (десериализация) это процесс восстановления объекта, из этих байт.

В этом приложении все сообщения, отправленные от сервера к клиенту, имеют тип String, которая содержит само сообщение.

2.2 Класс Server

Класс Server отвечает за всю логику работы серверного приложения.

Можно запустить сервер введя:  Java Server после предложения консоли. Всё будет выполняться в консольном режиме и сервер будет ждать соединения через порт 1500.

Для остановки сервера нужно использовать <CTRL> C.

2.3 Класс Client

Класс Client отвечает за всю логику работы клиентского приложения.

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

Java Client на консольный порт. После этого запускается клиентское приложение с именем пользователя Anonymous на локальном компьютере через порт 880. Таким образом, команда эквивалентна;

Java Client Анонимные 880 локальный.

После того как приложение запустилось в консольном режиме можно ввести:

Logout выйти и закрыть соединение;

WHOISIN чтобы получить список пользователей подключенных к серверу;

Все остальное это сообщение, которое будет транслироваться, с введённым именем пользователя, для всех клиентов чата.

2.4 Классы GUI

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

GUI здесь простой графический интерфейс. Является как можно более простым, без необычных шрифтов, цветов, иконок. Используется класс JTextArea.

2.4.1 Описание класса TextArea. С помощью класса TextArea можно создать многострочное поле заданной ширины и высоты, снабженное полосами просмотра. Класс TextArea создан на базе класса TextComponent, поэтому для работы с многострочными полями можно использовать методы этого класса.

Краткое описание класса TextArea приведено ниже:

Конструкторы:

 Создание поля без текста и без указания размеров public TextArea();

Создание поля без текста с указанием размеров public TextArea(int rows, int cols);

Создание поля с текстом без указания размеров public TextArea(String text);

Создание поля с текстом и с указанием размеров public TextArea(String text, int rows, int cols);

 Создание поля TextArea.

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

TextArea txt;

txt = new TextArea("Введите строку текста",5, 35);

Созданное поле добавляется в окно апплета методом add.

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

Компонент JTextArea позволяет пользователям вводить и редактировать несколько строк текста. Он прост в использовании, но позволяет работать только с неформатированными последовательностями символов. Этот компонент не поддерживает стили, по умолчанию в нем используется модель PlainDocument. Следовательно, данный компонент ориентирован на обработку обычного текста. JTextArea поддерживает стандартные команды редактирования (конкретный набор команд зависит от используемого стиля).

Несмотря на то, что компонент JTextArea позволяет редактировать текст, состоящий из нескольких строк, он не поддерживает прокрутку. Если прокрутка необходима, следует поместить JTextArea в состав JScrollPane. Именно в таком виде компонент JTextArea используется в большинстве приложений.

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

Компонент JTextArea не генерирует события действия. Набор событий ограничивается теми, которые были унаследованы от JTextComponent. В частности, при работе с данным компонентом возникают события, связанные с текстовым курсором. Он также генерирует события документа; это происходит при изменении модели. Для большинства приложений достаточно обработчика событий текстового курсора. Более того, работая с текстовой областью, можно вовсе отказаться от обработки событий. Приложению достаточно извлекать текст по мере необходимости.

Подобно остальным текстовым компонентам, JTextArea является подклассом JTextComponent. Это означает, что при работе с данным компонентом можно использовать все методы, определенные в JTextComponent. Можно извлечь содержимое текстовой области с помощью метода getText(). Выделенный текст доступен посредством метода getSelectedText(). Можно также выделять текст из программы, вызывая сначала метод setCaretPosition(), а затем moveCaretPosition().

  1.  РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ

3.1 Запуск сервера

Начать нужно с запуска серверного приложения «Server» на одном из компьютеров, подключенному к сети. Вводим номер порта 800 и нажимаем кнопку «Start».  Происходит подключение к серверу.

Рисунок 3.1 –  Подключение сервера

  1.  Запуск клиентского приложения

После запуска серверного приложения запускаем клиентское «Client».Вместо Anonymous прописывается имя пользователя, затем нажимаем кнопку Login. О том, что подключение произошло будет выведена запись типа: «Connection accepted localhost/127.0.0.1:800».

Рисунок 3.2 –  Подключение клиентского приложения

Запускаем следующее клиентское приложение от другого пользователя. Посмотреть, кто подключён, можно при помощи кнопки «Who is in». В текущих подключениях будет указанно количество подключенных пользователей, имя пользователей и время, дата их подключения.

Рисунок 3.3 – Текущие подключения

В итоге чат с сообщениями будет выглядеть примерно следующим образом:

Рисунок 3.4 – Чат с обменом сообщениями

Выход из приложения осуществляется нажатием кнопки «Logout». Появляется следующая запись: «Server has close the connection: java.io.EOFException».

Рисунок 3.5 – Выход из приложения

Для входа необходимо вновь ввести имя пользователя и нажать «Login».

ЗАКЛЮЧЕНИЕ

В ходе выполнения курсовой работы был получен работающий программный продукт, представляющий собой сетевое приложение – чат, предназначенный для отправки, получения сообщений. Данное приложение является очень простым в использовании. В перспективе, программу можно улучшить,  изменить  визуальное оформление и добавить дополнительные возможности, такие, как пересылка файлов, добавления смайликов в чат, редактирование текста перед отправкой пользователю и тому подобное.  Мною были приобретены навыки по объектно-ориентированному программированию. В программе использовались классы: Serializable, JFrame, JTextArea и др.

СПИСОК ИСПОЛЬЗУЕМЫХ ИСТОЧНИКОВ

[1]  http://stud-baza.ru/yazyik-Java-referat-informatika-programmirovanie

[2]  http://window.edu.ru/resource/397/58397/files/Eclipse_Java.pdf

[3]  Герберт Ш. Java. Полное руководство. 8-е изд. – СПб.: Москва, 2012. – 1140 с.: ил. – Парал.тит.англ.

[4] http://www.williamspublishing.com/PDF/5-8459-0385-8/part.pdf

ПРИЛОЖЕНИЕ А

ЛИСТИНГ ОСНОВНЫХ КЛАССОВ ПРИЛОЖЕНИЯ

КлассChatMessage

import java.io.*;

/*

* This class defines the different type of messages that will be exchanged between the

* Clients and the Server.

* When talking from a Java Client to a Java Server a lot easier to pass Java objects, no

* need to count bytes or to wait for a line feed at the end of the frame

*/

public class ChatMessage implements Serializable {

 protected static final long serialVersionUID = 1112122200L;

// The different types of message sent by the Client

// WHOISIN to receive the list of the users connected

// MESSAGE an ordinary message

// LOGOUT to disconnect from the Server

 static final int WHOISIN = 0, MESSAGE = 1, LOGOUT = 2;

 private int type;

 private String message;

 

// constructor

ChatMessage(int type, String message) {

 this.type = type;

 this.message = message;

}

 

// getters

 int getType() {

 return type;

}

String getMessage() {

 return message;

}

}

КлассServer

import java.io.*;

import java.net.*;

import java.text.SimpleDateFormat;

import java.util.*;

/*

* The server that can be run both as a console application or a GUI

*/

public class Server {

private static int uniqueId;   // a unique ID for each connection

// an ArrayList to keep the list of the Client

private ArrayList<ClientThread> al;

// if I am in a GUI

private ServerGUI sg;

// to display time

private SimpleDateFormat sdf;

// the port number to listen for connection

private int port;

// the boolean that will be turned of to stop the server

private boolean keepGoing;

 

/*

 *  server constructor that receive the port to listen to for connection as parameter

 *  in console

 */

public Server(int port) {

 this(port, null);

}

 

public Server(int port, ServerGUI sg) {

 // GUI or not

 this.sg = sg;

 // the port

 this.port = port;

 // to display hh:mm:ss

 sdf = new SimpleDateFormat("HH:mm:ss");

 // ArrayList for the Client list

 al = new ArrayList<ClientThread>();

}

 

public void start() {

 keepGoing = true;

 /* create socket server and wait for connection requests */

 try

 {

  // the socket used by the server

  ServerSocket serverSocket = new ServerSocket(port);

  // infinite loop to wait for connections

  while(keepGoing)

  {

   // format message saying we are waiting

   display("Server waiting for Clients on port " + port + ".");

   

   Socket socket = serverSocket.accept();   // accept connection

   // if I was asked to stop

   if(!keepGoing)

    break;

   ClientThread t = new ClientThread(socket);  // make a thread of it

   al.add(t);         // save it in the ArrayList

   t.start();

  }

  // I was asked to stop

  try {

   serverSocket.close();

   for(int i = 0; i < al.size(); ++i) {

    ClientThread tc = al.get(i);

    try {

    tc.sInput.close();

    tc.sOutput.close();

    tc.socket.close();

    }

    catch(IOException ioE) {

     // not much I can do

    }

   }

  }

  catch(Exception e) {

   display("Exception closing the server and clients: " + e);

  }

 }

 // something went bad

 catch (IOException e) {

           String msg = sdf.format(new Date()) + " Exception on new ServerSocket: " + e + "\n";

  display(msg);

 }

}  

   /*

    * For the GUI to stop the server

    */

protected void stop() {

 keepGoing = false;

 // connect to myself as Client to exit statement

 // Socket socket = serverSocket.accept();

 try {

  new Socket("localhost", port);

 }

 catch(Exception e) {

  // nothing I can really do

 }

}

/*

 * Display an event (not a message) to the console or the GUI

 */

private void display(String msg) {

 String time = sdf.format(new Date()) + " " + msg;

 if(sg == null)

  System.out.println(time);

 else

  sg.appendEvent(time + "\n");

}

/*

 *  to broadcast a message to all Clients

 */

private synchronized void broadcast(String message) {

 // add HH:mm:ss and \n to the message

 String time = sdf.format(new Date());

 String messageLf = time + " " + message + "\n";

 // display message on console or GUI

 if(sg == null)

  System.out.print(messageLf);

 else

  sg.appendRoom(messageLf);     // append in the room window

 

 // we loop in reverse order in case we would have to remove a Client

 // because it has disconnected

 for(int i = al.size(); --i >= 0;) {

  ClientThread ct = al.get(i);

  // try to write to the Client if it fails remove it from the list

  if(!ct.writeMsg(messageLf)) {

   al.remove(i);

   display("Disconnected Client " + ct.username + " removed from list.");

  }

 }

}

// for a client who logoff using the LOGOUT message

synchronized void remove(int id) {

 // scan the array list until we found the Id

 for(int i = 0; i < al.size(); ++i) {

  ClientThread ct = al.get(i);

  // found it

  if(ct.id == id) {

   al.remove(i);

   return;

  }

 }

}

 

/*

 *  To run as a console application just open a console window and:

 * > java Server

 * > java Server portNumber

 * If the port number is not specified 800 is used

 */

public static void main(String[] args) {

 // start server on port 800 unless a PortNumber is specified

 int portNumber = 800;

 switch(args.length) {

  case 1:

   try {

    portNumber = Integer.parseInt(args[0]);

   }

   catch(Exception e) {

    System.out.println("Invalid port number.");

    System.out.println("Usage is: > java Server [portNumber]");

    return;

   }

  case 0:

   break;

  default:

   System.out.println("Usage is: > java Server [portNumber]");

   return;

   

 }

 // create a server object and start it

 Server server = new Server(portNumber);

 server.start();

}

/** One instance of this thread will run for each client */

class ClientThread extends Thread {

 // the socket where to listen/talk

 Socket socket;

 ObjectInputStream sInput;

 ObjectOutputStream sOutput;

 // my unique id (easier for deconnection)

 int id;

 // the Username of the Client

 String username;

 // the only type of message a will receive

 ChatMessage cm;

 // the date I connect

 String date;

 // Constructore

 ClientThread(Socket socket) {

  // a unique id

  id = ++uniqueId;

  this.socket = socket;

  /* Creating both Data Stream */

  System.out.println("Thread trying to create Object Input/Output Streams");

  try

  {

   // create output first

   sOutput = new ObjectOutputStream(socket.getOutputStream());

   sInput  = new ObjectInputStream(socket.getInputStream());

   // read the username

   username = (String) sInput.readObject();

   display(username + " just connected.");

  }

  catch (IOException e) {

   display("Exception creating new Input/output Streams: " + e);

   return;

  }

  // have to catch ClassNotFoundException

  // but I read a String, I am sure it will work

  catch (ClassNotFoundException e) {

  }

           date = new Date().toString() + "\n";

 }

 // what will run forever

 public void run() {

  // to loop until LOGOUT

  boolean keepGoing = true;

  while(keepGoing) {

   // read a String (which is an object)

   try {

    cm = (ChatMessage) sInput.readObject();

   }

   catch (IOException e) {

    display(username + " Exception reading Streams: " + e);

    break;    

   }

   catch(ClassNotFoundException e2) {

    break;

   }

   // the messaage part of the ChatMessage

   String message = cm.getMessage();

   // Switch on the type of message receive

   switch(cm.getType()) {

   case ChatMessage.MESSAGE:

    broadcast(username + ": " + message);

    break;

   case ChatMessage.LOGOUT:

    display(username + " disconnected with a LOGOUT message.");

    keepGoing = false;

    break;

   case ChatMessage.WHOISIN:

    writeMsg("List of the users connected at " + sdf.format(new Date()) + "\n");

    // scan al the users connected

    for(int i = 0; i < al.size(); ++i) {

     ClientThread ct = al.get(i);

     writeMsg((i+1) + ") " + ct.username + " since " + ct.date);

    }

    break;

   }

  }

  // remove myself from the arrayList containing the list of the

  // connected Clients

  remove(id);

  close();

 }

 

 // try to close everything

 private void close() {

  // try to close the connection

  try {

   if(sOutput != null) sOutput.close();

  }

  catch(Exception e) {}

  try {

   if(sInput != null) sInput.close();

  }

  catch(Exception e) {};

  try {

   if(socket != null) socket.close();

  }

  catch (Exception e) {}

 }

 /*

  * Write a String to the Client output stream

  */

 private boolean writeMsg(String msg) {

  // if Client is still connected send the message to it

  if(!socket.isConnected()) {

   close();

   return false;

  }

  // write the message to the stream

  try {

   sOutput.writeObject(msg);

  }

  // if an error occurs, do not abort just inform the user

  catch(IOException e) {

   display("Error sending message to " + username);

   display(e.toString());

  }

  return true;

 }

}

}

Класс Client

import java.net.*;

import java.io.*;

import java.util.*;

/*

* The Client that can be run both as a console or a GUI

*/

public class Client  {

// for I/O

private ObjectInputStream sInput;  // to read from the socket

private ObjectOutputStream sOutput;  // to write on the socket

private Socket socket;

// if I use a GUI or not

private ClientGUI cg;

 

// the server, the port and the username

private String server, username;

private int port;

private static Scanner scan;

/*

 *  Constructor called by console mode

 *  server: the server address

 *  port: the port number

 *  username: the username

 */

Client(String server, int port, String username) {

 // which calls the common constructor with the GUI set to null

 this(server, port, username, null);

}

/*

 * Constructor call when used from a GUI

 * in console mode the ClienGUI parameter is null

 */

Client(String server, int port, String username, ClientGUI cg) {

 this.server = server;

 this.port = port;

 this.username = username;

 // save if we are in GUI mode or not

 this.cg = cg;

}

 

/*

 * To start the dialog

 */

public boolean start() {

 // try to connect to the server

 try {

  socket = new Socket(server, port);

 }

 // if it failed not much I can so

 catch(Exception ec) {

  display("Error connectiong to server:" + ec);

  return false;

 }

 

 String msg = "Connection accepted " + socket.getInetAddress() + ":" + socket.getPort();

 display(msg);

 

 /* Creating both Data Stream */

 try

 {

  sInput  = new ObjectInputStream(socket.getInputStream());

  sOutput = new ObjectOutputStream(socket.getOutputStream());

 }

 catch (IOException eIO) {

  display("Exception creating new Input/output Streams: " + eIO);

  return false;

 }

 // creates the Thread to listen from the server

 new ListenFromServer().start();

 // Send our username to the server this is the only message that we

 // will send as a String. All other messages will be ChatMessage objects

 try

 {

  sOutput.writeObject(username);

 }

 catch (IOException eIO) {

  display("Exception doing login : " + eIO);

  disconnect();

  return false;

 }

 // success we inform the caller that it worked

 return true;

}

/*

 * To send a message to the console or the GUI

 */

private void display(String msg) {

 if(cg == null)

  System.out.println(msg);      // println in console mode

 else

  cg.append(msg + "\n");  // append to the ClientGUI JTextArea (or whatever)

}

 

/*

 * To send a message to the server

 */

void sendMessage(ChatMessage msg) {

 try {

  sOutput.writeObject(msg);

 }

 catch(IOException e) {

  display("Exception writing to server: " + e);

 }

}

/*

 * When something goes wrong

 * Close the Input/Output streams and disconnect not much to do in the catch clause

 */

private void disconnect() {

 try {

  if(sInput != null) sInput.close();

 }

 catch(Exception e) {} // not much else I can do

 try {

  if(sOutput != null) sOutput.close();

 }

 catch(Exception e) {} // not much else I can do

       try{

  if(socket != null) socket.close();

 }

 catch(Exception e) {} // not much else I can do

 

 // inform the GUI

 if(cg != null)

  cg.connectionFailed();

  

}

/*

 * To start the Client in console mode use one of the following command

 * > java Client

 * > java Client username

 * > java Client username portNumber

 * > java Client username portNumber serverAddress

 * at the console prompt

 * If the portNumber is not specified 800 is used

 * If the serverAddress is not specified "localHost" is used

 * If the username is not specified "Anonymous" is used

 * > java Client

 * is equivalent to

 * > java Client Anonymous 800 localhost

 * are eqquivalent

 *

 * In console mode, if an error occurs the program simply stops

 * when a GUI id used, the GUI is informed of the disconnection

 */

public static void main(String[] args) {

 // default values

 int portNumber = 800;

 String serverAddress = "localhost";

 String userName = "Anonymous";

 // depending of the number of arguments provided we fall through

 switch(args.length) {

  // > javac Client username portNumber serverAddr

  case 3:

   serverAddress = args[2];

  // > javac Client username portNumber

  case 2:

   try {

    portNumber = Integer.parseInt(args[1]);

   }

   catch(Exception e) {

    System.out.println("Invalid port number.");

    System.out.println("Usage is: > java Client [username] [portNumber] [serverAddress]");

    return;

   }

  // > javac Client username

  case 1:

   userName = args[0];

  // > java Client

  case 0:

   break;

  // invalid number of arguments

  default:

   System.out.println("Usage is: > java Client [username] [portNumber] {serverAddress]");

  return;

 }

 // create the Client object

 Client client = new Client(serverAddress, portNumber, userName);

 // test if we can start the connection to the Server

 // if it failed nothing we can do

 if(!client.start())

  return;

 

 scan = new Scanner(System.in);

 // loop forever for message from the user

 while(true) {

  System.out.print("> ");

  // read message from user

  String msg = scan.nextLine();

  // logout if message is LOGOUT

  if(msg.equalsIgnoreCase("LOGOUT")) {

   client.sendMessage(new ChatMessage(ChatMessage.LOGOUT, ""));

   // break to do the disconnect

   break;

  }

  // message WhoIsIn

  else if(msg.equalsIgnoreCase("WHOISIN")) {

   client.sendMessage(new ChatMessage(ChatMessage.WHOISIN, ""));    

  }

  else {    // default to ordinary message

   client.sendMessage(new ChatMessage(ChatMessage.MESSAGE, msg));

  }

 }

 // done disconnect

 client.disconnect();

}

/*

 * a class that waits for the message from the server and append them to the JTextArea

 * if we have a GUI or simply System.out.println() it in console mode

 */

class ListenFromServer extends Thread {

 public void run() {

  while(true) {

   try {

    String msg = (String) sInput.readObject();

    // if console mode print the message and add back the prompt

    if(cg == null) {

     System.out.println(msg);

     System.out.print("> ");

    }

    else {

     cg.append(msg);

    }

   }

   catch(IOException e) {

    display("Server has close the connection: " + e);

    if(cg != null)

     cg.connectionFailed();

    break;

   }

   // can't happen with a String object but need the catch anyhow

   catch(ClassNotFoundException e2) {

   }

  }

 }

}

}

Класс ServerGUI

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

/*

* The server as a GUI

*/

public class ServerGUI extends JFrame implements ActionListener, WindowListener {

 

private static final long serialVersionUID = 1L;

// the stop and start buttons

private JButton stopStart;

// JTextArea for the chat room and the events

private JTextArea chat, event;

// The port number

private JTextField tPortNumber;

// my server

private Server server;

 

 

// server constructor that receive the port to listen to for connection as parameter

ServerGUI(int port) {

 super("Chat Server");

 server = null;

 // in the NorthPanel the PortNumber the Start and Stop buttons

 JPanel north = new JPanel();

 north.add(new JLabel("Port number: "));

 tPortNumber = new JTextField("  " + port);

 north.add(tPortNumber);

 // to stop or start the server, we start with "Start"

 stopStart = new JButton("Start");

 stopStart.addActionListener(this);

 north.add(stopStart);

 add(north, BorderLayout.NORTH);

 

 // the event and chat room

 JPanel center = new JPanel(new GridLayout(2,1));

 chat = new JTextArea(80,80);

 chat.setEditable(false);

 appendRoom("Chat room.\n");

 center.add(new JScrollPane(chat));

 event = new JTextArea(80,80);

 event.setEditable(false);

 appendEvent("Events log.\n");

 center.add(new JScrollPane(event));

 add(center);

 

 // need to be informed when the user click the close button on the frame

 addWindowListener(this);

 setSize(400, 600);

 setVisible(true);

}  

// append message to the two JTextArea

// position at the end

void appendRoom(String str) {

 chat.append(str);

 chat.setCaretPosition(chat.getText().length() - 1);

}

void appendEvent(String str) {

 event.append(str);

 event.setCaretPosition(chat.getText().length() - 1);

 

}

 

// start or stop where clicked

public void actionPerformed(ActionEvent e) {

 // if running we have to stop

 if(server != null) {

  server.stop();

  server = null;

  tPortNumber.setEditable(true);

  stopStart.setText("Start");

  return;

 }

      // OK start the server

 int port;

 try {

  port = Integer.parseInt(tPortNumber.getText().trim());

 }

 catch(Exception er) {

  appendEvent("Invalid port number");

  return;

 }

 // ceate a new Server

 server = new Server(port, this);

 // and start it as a thread

 new ServerRunning().start();

 stopStart.setText("Stop");

 tPortNumber.setEditable(false);

}

 

// entry point to start the Server

public static void main(String[] arg) {

 // start server default port 800

 new ServerGUI(800);

}

/*

 * If the user click the X button to close the application

 * I need to close the connection with the server to free the port

 */

public void windowClosing(WindowEvent e) {

 // if my Server exist

 if(server != null) {

  try {

   server.stop();   // ask the server to close the conection

  }

  catch(Exception eClose) {

  }

  server = null;

 }

 // dispose the frame

 dispose();

 System.exit(0);

}

// I can ignore the other WindowListener method

public void windowClosed(WindowEvent e) {}

public void windowOpened(WindowEvent e) {}

public void windowIconified(WindowEvent e) {}

public void windowDeiconified(WindowEvent e) {}

public void windowActivated(WindowEvent e) {}

public void windowDeactivated(WindowEvent e) {}

/*

 * A thread to run the Server

 */

class ServerRunning extends Thread {

 public void run() {

  server.start();         // should execute until if fails

  // the server failed

  stopStart.setText("Start");

  tPortNumber.setEditable(true);

  appendEvent("Server crashed\n");

  server = null;

 }

}

}

Класс ClientGUI

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

/*

* The Client with its GUI

*/

public class ClientGUI extends JFrame implements ActionListener {

private static final long serialVersionUID = 1L;

// will first hold "Username:", later on "Enter message"

private JLabel label;

// to hold the Username and later on the messages

private JTextField tf;

// to hold the server address an the port number

private JTextField tfServer, tfPort;

// to Logout and get the list of the users

private JButton login, logout, whoIsIn;

// for the chat room

private JTextArea ta;

// if it is for connection

private boolean connected;

// the Client object

private Client client;

// the default port number

private int defaultPort;

private String defaultHost;

// Constructor connection receiving a socket number

ClientGUI(String host, int port) {

 super("Chat Client");

 defaultPort = port;

 defaultHost = host;

 

 // The NorthPanel with:

 JPanel northPanel = new JPanel(new GridLayout(3,1));

 // the server name anmd the port number

 JPanel serverAndPort = new JPanel(new GridLayout(1,5, 1, 3));

 // the two JTextField with default value for server address and port number

 tfServer = new JTextField(host);

 tfPort = new JTextField("" + port);

 tfPort.setHorizontalAlignment(SwingConstants.RIGHT);

 serverAndPort.add(new JLabel("Server Address:  "));

 serverAndPort.add(tfServer);

 serverAndPort.add(new JLabel("Port Number:  "));

 serverAndPort.add(tfPort);

 serverAndPort.add(new JLabel(""));

 // adds the Server an port field to the GUI

 northPanel.add(serverAndPort);

 // the Label and the TextField

 label = new JLabel("Enter your username below", SwingConstants.CENTER);

 northPanel.add(label);

 tf = new JTextField("Anonymous");

 tf.setBackground(Color.WHITE);

 northPanel.add(tf);

 add(northPanel, BorderLayout.NORTH);

 // The CenterPanel which is the chat room

 ta = new JTextArea("Welcome to the Chat room\n", 80, 80);

 JPanel centerPanel = new JPanel(new GridLayout(1,1));

 centerPanel.add(new JScrollPane(ta));

 ta.setEditable(false);

 add(centerPanel, BorderLayout.CENTER);

 // the 3 buttons

 login = new JButton("Login");

 login.addActionListener(this);

 logout = new JButton("Logout");

 logout.addActionListener(this);

 logout.setEnabled(false);  // you have to login before being able to logout

 whoIsIn = new JButton("Who is in");

 whoIsIn.addActionListener(this);

 whoIsIn.setEnabled(false);  // you have to login before being able to Who is in

 JPanel southPanel = new JPanel();

 southPanel.add(login);

 southPanel.add(logout);

 southPanel.add(whoIsIn);

 add(southPanel, BorderLayout.SOUTH);

 setDefaultCloseOperation(EXIT_ON_CLOSE);

 setSize(600, 600);

 setVisible(true);

 tf.requestFocus();

}

// called by the Client to append text in the TextArea

void append(String str) {

 ta.append(str);

 ta.setCaretPosition(ta.getText().length() - 1);

}

// called by the GUI is the connection failed

// we reset our buttons, label, textfield

void connectionFailed() {

 login.setEnabled(true);

 logout.setEnabled(false);

 whoIsIn.setEnabled(false);

 label.setText("Enter your username below");

 tf.setText("Anonymous");

 // reset port number and host name as a construction time

 tfPort.setText("" + defaultPort);

 tfServer.setText(defaultHost);

 // let the user change them

 tfServer.setEditable(false);

 tfPort.setEditable(false);

 // don't react to a <CR> after the username

 tf.removeActionListener(this);

 connected = false;

}

 

/*

* Button or JTextField clicked

*/

public void actionPerformed(ActionEvent e) {

 Object o = e.getSource();

 // if it is the Logout button

 if(o == logout) {

  client.sendMessage(new ChatMessage(ChatMessage.LOGOUT, ""));

  return;

 }

 // if it the who is in button

 if(o == whoIsIn) {

  client.sendMessage(new ChatMessage(ChatMessage.WHOISIN, ""));    

  return;

 }

 // ok it is coming from the JTextField

 if(connected) {

  // just have to send the message

  client.sendMessage(new ChatMessage(ChatMessage.MESSAGE, tf.getText()));    

  tf.setText("");

  return;

 }

 

 if(o == login) {

  // ok it is a connection request

  String username = tf.getText().trim();

  // empty username ignore it

  if(username.length() == 0)

   return;

  // empty serverAddress ignore it

  String server = tfServer.getText().trim();

  if(server.length() == 0)

   return;

  // empty or invalid port numer, ignore it

  String portNumber = tfPort.getText().trim();

  if(portNumber.length() == 0)

   return;

  int port = 0;

  try {

   port = Integer.parseInt(portNumber);

  }

  catch(Exception en) {

   return;   // nothing I can do if port number is not valid

  }

  // try creating a new Client with GUI

  client = new Client(server, port, username, this);

  // test if we can start the Client

  if(!client.start())

   return;

  tf.setText("");

  label.setText("Enter your message below");

  connected = true;

  

  // disable login button

  login.setEnabled(false);

  // enable the 2 buttons

  logout.setEnabled(true);

  whoIsIn.setEnabled(true);

  // disable the Server and Port JTextField

  tfServer.setEditable(false);

  tfPort.setEditable(false);

  // Action listener for when the user enter a message

  tf.addActionListener(this);

 }

}

// to start the whole thing the server

public static void main(String[] args) {

 new ClientGUI("localhost", 800);

}

}

ПРИЛОЖЕНИЕ Б

ДОКУМЕНТАЦИЯ JAVA

ChatMessage

Server


Client


ServerGUI

ClientGUI

PAGE   \* MERGEFORMAT4



 

Другие похожие работы, которые могут вас заинтересовать.
8392. Основы объектно-ориентированного программирования 10.04 KB
  В начале 80х годов в той же Веll Lаbоrtory Бьерном Страуструпом в результате дополнения и расширения языка С был создан новый по сути язык получивший название С с классами . Знакомство с классами. Определение класса и cоздание его объекта. Общий синтаксис класса можно определить с помощью конструкции...
3958. Основные понятия объектно-ориентированного программирования 8.23 KB
  В языках программирования для процедур используются также термины функция подпрограмма или метод. Примерами языков программирования ориентированными на процедурное программирование являются языки C Bsic и Pscl. Реализация объектноориентированного программирования в JvScript Язык JvScript является объектноориентированным языком программирования в котором реализован второй подход к созданию объектов с определением для новых объектов набора свойств и методов а также клонированием существующих объектов из их прототипов хотя в список...
20838. Изучение истории возникновения программирования и основных принципов и подходов при создании языка программирования 705.86 KB
  Для достижения поставленной цели необходимо решить следующие задачи: Проанализировать информационные источники по технологиям программирования; Рассмотреть историю развития технологий программирования; Выявить этапы развития технологий программирования. Создать базу данных для хранения информации о сотрудниках. Язык программирования – формализованный язык для описания алгоритма решения задачи на компьютере. Для автоматизации программирования разрабатывался для каждой ЭВМ свой автокод или Ассемблер.
18329. Разработка программного обеспечения для призывного пункта на языке программирования Delphi 8.32 MB
  Одной из составляющих этой системы является подсистема учета призывников или если быть более точным учета и формирование команд для отправки на срочную воинскую службу в вооруженные силы Республики Казахстан. Основной целью данной дипломной работы является создание программного комплекса в области ведения учета и формирования различного вида отчетов в области создания пакетов прикладных программ в частности системы формирования контингента...
9991. Создание программного продукта для более удобной работы c операторами языка C++ 682.67 KB
  Шифрование текста необходимо для защиты информации от посторонних для кого она не предназначена. Шифрование – это способ защиты данных от несанкционированного использования. Шифрование для защиты информации полагается на разделы математики, называемой криптографией.
3481. Розробка програмного продукту «Годинник» засобами інтегрованого об’єктно-орієнтованого середовища мови програмування JAVA, та дослідження його основних методів та класів 748.56 KB
  Java орієнтована на Internet, і найпоширеніше її застосування - невеликі програми, аплети, які запускаються в браузері і є частиною HTML-сторінок. Також мова Java є обєктно-орієнтованою і поставляється з досить обємною бібліотекою класів. На даний момент мова програмування Java є однією з самих кращих мов програмування, якою користуються серйозним програмістам.
3768. Освоение технологии структурного программирования на языке Турбо Паскаль 60.89 KB
  Освоение методики нисходящей разработки (проектирования) программы методом пошаговой детализации с помощью псевдокода при решении задач с помощью ПК. Освоение методов структурного программирования при разработке и создании программы на языке Турбо Паскаль для циклического вычислительного процесса с известным числом повторений.
6477. Система команд микроконтроллеров MCS-51 и основы программирования на языке Ассемблер 380.51 KB
  Характеристика системы команды микроконтроллеров MCS51 Микроконтроллеры семейства MCS51 относятся к классу процессоров с аппаратным принципом управления. Каждая команда несет в себе два “сообщения†для процессора: действие которое нужно выполнить – зашифровано в коде операции; как получить операнды для выполнения этого действия – эта информация содержится в адресной части команды. Для удобства составления программ каждому двоичному коду операции поставлено в соответствие буквенное обозначение команды – т. мнемоника...
8198. Создание информационно-программного комплекса 737.21 KB
  В процессе функционирования предприятия заключаются двухсторонние единовременные договора с поставщиками. После отгрузки поставляемые товары поступают на склад в количестве, указанном в заказе
3604. Освоение технологии структурного программирования и применения стандартных методов работы с двумерными массивами при разработке и создании программы на языке Турбо Паскаль 52.5 KB
  Освоение методов структурного программирования при разработке и создании программы на языке Турбо Паскаль для обработки двумерных массивов. Освоение методики нисходящей разработки (проектирования) программы методом пошаговой детализации с помощью псевдокода при решении задач с помощью ПК.
© "REFLEADER" http://refleader.ru/
Все права на сайт и размещенные работы
защищены законом об авторском праве.