ИКПИ. Пример отчета по практике
.pdfМИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ, СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ
«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА» (СПбГУТ)
________________________________________
Факультет Инфокоммуникационных сетей и систем Кафедра Программной инженерии и вычислительной техники
Отчет по производственной практике
Предприятие: ООО «НТЦ Севентест»
Период прохождения практики: 28.06.21 – 15.07.21
Выполнил Коваленко Леонид Александрович, ИКПИ-84
(Ф.И.О., № группы)
Подпись студента_____________________
Руководитель практики от базы практики:
_____________________________________
(Ф.И.О., Подпись)
Оценка ______________________________
Руководитель практики от кафедры:
_____________________________________
(кафедра, Ф.И.О.)
_____________________________________
(Подпись)
Санкт-Петербург
2021
СОДЕРЖАНИЕ
Введение......................................................................................................... |
3 |
Задания на производственную практику .................................................... |
3 |
Выполнение заданий..................................................................................... |
4 |
Первое задание .......................................................................................... |
4 |
Второе задание ........................................................................................ |
12 |
Дневник производственной практики....................................................... |
38 |
Заключение .................................................................................................. |
39 |
Список литературы ..................................................................................... |
39 |
2
ВВЕДЕНИЕ Производственная практика — практическая часть учебного процесса
подготовки квалифицированных рабочих и специалистов, проходящая, как правило, на различных предприятиях в условиях реального производства. Является заключительной частью учебной практики, проходящей в учебном заведении. Во время производственной практики происходит закрепление и конкретизация результатов теоретического учебно-практического обучения, приобретение студентами умения и навыков практической работы по присваиваемой квалификации и избранной специальности или профессии.
Перенос учебного процесса в условия, максимально схожие с обстановкой будущей профессиональной деятельностью студента, – обязательный этап на пути получения высшего образования, обусловленный требованиями госстандартов и регламентированный приказом Минобразования и науки РФ № 1383.
ЗАДАНИЯ НА ПРОИЗВОДСТВЕННУЮ ПРАКТИКУ
1.Разработать клиент-серверное приложение с помощью CORBA.
2.Разработать библиотеку для парсинга файлов выписки плана нумерации ФАС.
3
ВЫПОЛНЕНИЕ ЗАДАНИЙ Первое задание
IDL — декларативный язык для формального описания интерфейсов взаимодействия клиентов и серверов в распределенных приложениях. IDL не привязан к какому-либо языку программирования, но для большинства современных языков программирования существуют спецификации,
определяющие правила трансляции конструкций IDL в конструкции этих языков.
Описание интерфейса для первого задания представлено в таблице 1.
Таблица 1. Описание интерфейса взаимодействия клиента и сервера
Data.idl
module Data
{
interface ServiceA
{
string HelloWorld(in string message);
boolean Div(in long a, in long b, out long r); void CaesarCipher(inout string str, in short k);
};
};
Конструкция module определяет пространство имен, в котором будут существовать включенные в нее интерфейсы.
Конструкция interface определяет программный интерфейс, с помощью которого объекты общаются друг с другом.
Втеле конструкции interface объявляются операции, которые должен быть способен выполнять сервер по запросу клиента.
Врезультате компиляции будут созданы 2 файла: Data.hh и DataSK.cc.
Они содержат описание интерфейса CServiceA и вспомогательных классов.
Серверная часть проекта состоит из 5 файлов:
1.Server/CServiceA.h и Server/CServiceA.cpp (см. таблицы 2-3) содержат реализацию интерфейса CServiceA — класс CServiceA_i.
2.Server/CServiceARunner.h и Server/CServiceARunner.cpp (см. таблицы 4-
5)содержат класс, используемый для инициализации брокера объектных запросов и запуска сервисов.
3.Server/Server.cpp (см. таблицу 6) описывает работу точки входа.
4
Таблица 2. Файл Server/CServiceA.h Server/CServiceA.h
#ifndef CSERVICEA_H #define CSERVICEA_H
#include "../Data.hh"
class CServiceA_i : public POA_Data::ServiceA,
public PortableServer::RefCountServantBase
{
public: CServiceA_i();
virtual ~CServiceA_i();
virtual char *HelloWorld(const char *) override;
virtual CORBA::Boolean Div(CORBA::Long, CORBA::Long, CORBA::Long &) override; virtual void CaesarCipher(char *&, CORBA::Short) override;
};
#endif // CSERVICEA_H
Таблица 3. Файл Server/CServiceA.cpp Server/CServiceA.cpp
#include "CServiceA.h" #include <cstring> #include <iostream>
CServiceA_i::CServiceA_i()
{
}
CServiceA_i::~CServiceA_i()
{
}
char *CServiceA_i::HelloWorld(const char *)
{
return CORBA::string_dup("Hello, world!");
}
CORBA::Boolean CServiceA_i::Div(CORBA::Long a, CORBA::Long b, CORBA::Long &r)
{
r = 0;
if (b == 0)
{
r = 0;
return false; // error
}
r = a / b;
return true; // success
}
void CServiceA_i::CaesarCipher(char *&str, CORBA::Short k)
{
for (size_t i = 0, size = strlen(str); i < size; ++i)
{
bool lower = ('a' <= str[i] && str[i] <= 'z'); bool upper = ('A' <= str[i] && str[i] <= 'Z'); if (lower || upper)
{
short t = ('a' ^ (upper ? 32 : 0));
str[i] = static_cast<char>((str[i] - t + k) % ('z' - 'a' + 1) + t);
}
}
}
5
Таблица 4. Файл Server/CServiceARunner.h Server/CServiceARunner.h
#ifndef CSERVICEARUNNER_H #define CSERVICEARUNNER_H
#include "../Data.hh" #include "CServiceA.h" class CServiceARunner
{
public:
CServiceARunner(int argc, char **argv); ~CServiceARunner();
void run(); CORBA::String_var get_ior();
private:
//Брокер объектных запросов (Object Request Broker, ORB) CORBA::ORB_var m_orb;
//Сервант
PortableServer::Servant_var<CServiceA_i> m_c_service_a;
//Строковая IOR ссылка на объект-сервант
CORBA::String_var m_ior;
//POA
PortableServer::POA_var m_poa; // RootPOA
CORBA::Object_var m_root_poa_obj; // POA менеджер
PortableServer::POAManager_var poa_manager; // ObjectID
PortableServer::ObjectId_var m_c_service_a_oid;
};
#endif // CSERVICEARUNNER_H
Таблица 5. Файл Server/CServiceARunner.cpp Server/CServiceARunner.cpp
#include "CServiceARunner.h" #include "CServiceA.h" #include "../Data.hh"
#include <utility> #include <iostream>
CServiceARunner::CServiceARunner(int argc, char **argv)
{
//Инициализация брокера объектных запросов
//(Object Request Broker, ORB)
m_orb = CORBA::ORB_init(argc, argv); if (CORBA::is_nil(m_orb))
{
throw std::runtime_error("CORBA::ORB_init failed.");
}
//Получение доступа к переносимому объектному адаптеру по умолчанию
//(Root Portable Object Adapter, RootPOA)
m_root_poa_obj = m_orb->resolve_initial_references("RootPOA"); if (CORBA::is_nil(m_root_poa_obj))
{
throw std::runtime_error("CORBA::ORB->resolve_initial_references(\"RootPOA\") failed.");
}
m_poa = PortableServer::POA::_narrow(m_root_poa_obj); if (CORBA::is_nil(m_poa))
{
throw std::runtime_error("PortableServer::POA::_narrow failed.");
}
PortableServer::POAManager_var poa_manager = m_poa->the_POAManager(); if (CORBA::is_nil(poa_manager))
{
throw std::runtime_error("PortableServer::POA->the_POAManager() failed.");
}
// Создание серванта m_c_service_a = new CServiceA_i();
// Активация серванта в RootPOA (переносимом объектном адаптере по умолчанию)
6
Server/CServiceARunner.cpp
m_c_service_a_oid = m_poa->activate_object(m_c_service_a);
//Запоминание строковой IOR ссылки на объект-сервант
//(Interoperable Object Reference, IOR)
m_ior = m_orb->object_to_string(m_c_service_a->_this()); // Получение корневого контекста именования
CORBA::Object_var name_service_obj = m_orb->resolve_initial_references("NameService"); if (CORBA::is_nil(name_service_obj))
{
throw std::runtime_error("CORBA::ORB->resolve_initial_references(\"NameService\") failed.");
}
CosNaming::NamingContext_var naming_context = CosNaming::NamingContext::_narrow(name_service_obj); if (CORBA::is_nil(naming_context))
{
throw std::runtime_error("CosNaming::NamingContext::_narrow failed.");
}
//Привязка к службе имен CORBA CosNaming::Name name; name.length(1);
name[0].id = "DataService"; name[0].kind = "Context";
naming_context->rebind(name, m_c_service_a->_this());
//Активация POA Manager
poa_manager->activate();
}
CServiceARunner::~CServiceARunner()
{
try
{
m_orb->destroy(); // Уничтожение объекта ORB
}
catch (...)
{
std::cerr << "CORBA::ORB->destroy exception occurred." << std::endl;
}
}
void CServiceARunner::run()
{
m_orb->run();
}
CORBA::String_var CServiceARunner::get_ior()
{
return m_ior;
}
Таблица 6. Файл Server/Server.cpp Server/Server.cpp
#include <iostream>
#include "CServiceARunner.h" #include "../Data.hh"
int main(int argc, char **argv)
{
CServiceARunner runner(argc, argv); std::cout << runner.get_ior() << std::endl; runner.run();
return 0;
}
7
Клиентская часть проекта состоит из 3 файлов:
1.Client/CRequestServiceA.h и Client/CRequestServiceA.cpp (см. таблицы
7-8) содержат класс, используемый для инициализации брокера объектных запросов и запуска сервисов.
2.Client/Client.cpp (см. таблицу 9) описывает работу точки входа.
Таблица 7. Файл Client/CRequestServiceA.h Client/CRequestServiceA.h
#ifndef CREQUESTSERVICEA_H #define CREQUESTSERVICEA_H
#include <utility> #include "../Data.hh"
class CRequestServiceA
{
public:
CRequestServiceA(int argc, char **argv); ~CRequestServiceA();
CORBA::String_var RequestHelloWorld(CORBA::String_var); std::pair<CORBA::Long, bool> RequestDiv(CORBA::Long, CORBA::Long); CORBA::String_var RequestCaesarCipher(CORBA::String_var, CORBA::Short);
private:
//Объект, связанный с брокером объектных запросов (Object Request Broker, ORB)
CORBA::ORB_var m_orb;
//Объект посредством которого осуществляются запросы
Data::ServiceA_var m_obj;
};
#endif // CREQUESTSERVICEA_H
Таблица 8. Файл Client/CRequestServiceA.cpp Client/CRequestServiceA.cpp
#include <stdexcept> #include <iostream> #include <utility>
#include "CRequestServiceA.h" #include "../Data.hh"
CRequestServiceA::CRequestServiceA(int argc, char **argv)
{
//Инициализация брокера объектных запросов (Object Request Broker, ORB) m_orb = CORBA::ORB_init(argc, argv);
if (CORBA::is_nil(m_orb))
{
throw std::runtime_error("CORBA::ORB_init failed.");
}
//Получение корневого контекста именования
CORBA::Object_var ns_obj = m_orb->resolve_initial_references("NameService"); if (CORBA::is_nil(ns_obj))
{
throw std::runtime_error("CORBA::ORB->resolve_initial_references failed.");
}
CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(ns_obj); if (CORBA::is_nil(nc))
{
throw std::runtime_error("CosNaming::NamingContext::_narrow failed.");
}
// Получение доступа к серверу
CosNaming::Name name; name.length(1);
name[0].id = "DataService";
8
Client/CRequestServiceA.cpp
name[0].kind = "Context"; CORBA::Object_var obj = nc->resolve(name); if (CORBA::is_nil(obj))
{
throw std::runtime_error("CosNaming::NamingContext->resolve failed.");
}
// Получение доступа к запрашиваемому объекту m_obj = Data::ServiceA::_narrow(obj);
if (CORBA::is_nil(obj))
{
throw std::runtime_error("Data::ServiceA::_narrow failed.");
}
}
CRequestServiceA::~CRequestServiceA()
{
try
{
m_orb->destroy(); // Уничтожение объекта ORB
}
catch (...)
{
std::cerr << "Orb destroy exception occurred." << std::endl;
}
}
CORBA::String_var CRequestServiceA::RequestHelloWorld(CORBA::String_var message_svar)
{
return m_obj->HelloWorld(message_svar);
}
std::pair<CORBA::Long, bool> CRequestServiceA::RequestDiv(CORBA::Long a, CORBA::Long b)
{
CORBA::Long c = 0;
CORBA::Boolean response = m_obj->Div(a, b, c); return {c, response};
}
CORBA::String_var CRequestServiceA::RequestCaesarCipher(CORBA::String_var message_svar, CORBA::Short k)
{
CORBA::String_INOUT_arg str(message_svar); m_obj->CaesarCipher(str, k);
return CORBA::string_dup(str);
}
Таблица 9. Файл Client/Client.cpp Client/Client.cpp
#include "CRequestServiceA.h" #include <iostream>
int main(int argc, char **argv)
{
//В конструкторе устанавливается связь с сервером CORBA
CRequestServiceA requestServiceA(argc, argv);
//Отправка запросов, получение и вывод ответов
auto responseHelloWorld = requestServiceA.RequestHelloWorld("Hello"); auto responseDiv = requestServiceA.RequestDiv(10, 5);
auto responseCaesarCipher = requestServiceA.RequestCaesarCipher("Hello, world!", 3); std::cout << "Response (HelloWorld): " << responseHelloWorld << std::endl;
std::cout << "Response (Div, 10/2): " << responseDiv.first << " (div error: " << !responseDiv.second << ')' << std::endl;
std::cout << "Response (CaesarCipher): " << responseCaesarCipher << std::endl; return 0;
}
9
Сборочный файл представлен в табл. 10.
Таблица 10. Сборочный файл Makefile Makefile
.PHONY : all clean_all clean CC=g++
CPPFLAGS=-std=c++11 -g -Werror -pedantic-errors -Wredundant-decls \ -Wall -Wextra -Wpedantic -Wcast-align -Wcast-qual \ -Wconversion -Wctor-dtor-privacy -Wduplicated-branches \ -Wduplicated-cond -Wextra-semi -Wfloat-equal -Wlogical-op \
-Wnon-virtual-dtor -Woverloaded-virtual -Wsign-conversion -Wsign-promo OMNI_HOME=/opt
INCLUDES=-I$(OMNI_HOME)/include LIBS=-lomniORB4 -lomnithread -lomniDynamic4 SERVER_SOURCES=$(wildcard ./Server/*.cpp) CLIENT_SOURCES=$(wildcard ./Client/*.cpp) SERVER_OBJECTS=$(SERVER_SOURCES:.cpp=.o) CLIENT_OBJECTS=$(CLIENT_SOURCES:.cpp=.o) SERVER_RUN=ServerRun
CLIENT_RUN=ClientRun
all: $(SERVER_RUN) $(CLIENT_RUN)
$(SERVER_RUN): DataSK.o $(SERVER_OBJECTS)
$(CC) -g -o $(SERVER_RUN) -L$(OMNI_HOME)/lib DataSK.o $(SERVER_OBJECTS) $(LIBS)
$(SERVER_OBJECTS): DataSK.o $(SERVER_SOURCES)
$(foreach src,$(SERVER_SOURCES),$(CC) $(CPPFLAGS) -c $(src) -o $(src:.cpp=.o) &&) true
$(CLIENT_RUN): DataSK.o $(CLIENT_OBJECTS)
$(CC) -g -o $(CLIENT_RUN) -L$(OMNI_HOME)/lib DataSK.o $(CLIENT_OBJECTS) $(LIBS)
$(CLIENT_OBJECTS): DataSK.o $(CLIENT_SOURCES)
$(foreach src,$(CLIENT_SOURCES),$(CC) $(CPPFLAGS) -c $(src) -o $(src:.cpp=.o) &&) true
DataSK.o: DataSK.cc Data.hh
$(CC) -c DataSK.cc
DataSK.cc Data.hh: Data.idl
omniidl -bcxx Data.idl
clean_all: clean
rm -f ./$(SERVER_RUN) rm -f ./$(CLIENT_RUN)
clean:
rm -f ./*.o rm -f ./*.hh rm -f ./*SK.cc
rm -f ./Server/*.o rm -f ./Client/*.o
10