Московский Государственный Институт Электроники и Математеки
кафедра ИКТ
Курсовая работа по предмету:
Сетевые технологии.
Тема работы:
Распределенная служба кодирования
Выполнил
студент группы С-64
Белехов В
Принял
Орлов Петр
Москва 2009 год
Белехов Владимир Николаевич – Выполнял работу.
Андреев Дмитрий Рубенович – Подготовил постановку задачи и техническое задание.
Сагратян Асатур Ашаотович – Помощь, google.
Ключевые слова:
Распределеный, кодирование, клиент-сервер, база данных.
Приложения:
Листинги: сервер-приложение, клиент-приложение, конфиги к ним, кодирующий скрипт.
Источники: для работы с mysql, libcurl.
Цель работы: Разработать клиент-серверное приложение распределенния задач кодирования.
Методолгия:Научный тык.
Степень внедрения: Отладка.
Область применения: кодирование видео.
Значимость работы: повышает эффективность кодирования видео, сервером СОВА
Сервер-приложение server.c. 14
Кодирующий скрипт encode_script.sh.. 19
Клиент-Приложение client.c. 20
MySQL dump тестовой базы данных. 27
СОВА – Система Организации Видео Архива
РСК – Распределенная Служба Кодирования
Система Организации Видео Архива (СОВА) на каждый добавленный видеофайл, помимо изображений (раскадровка и превью-кадр) создаётся потоковая веб версия (h.264, x264, mp4) и прокси копия - копия низкого разрешения (mpeg4, DivX). Это накладывает на сервер большую нагрузку по кодированию видео, например h.264 версия кодируется 2-3 риалтайма. При этом в массе своей видеофайлы небольшой длины, однако количество их велико. Для разгрузки сервера и ускорения кодирования целесообразно делегировать задачи по кодированию различным компьютерам (например простаивающим в ночное время машинным залам кафедры). Это и является задачей разрабатываемой системы.
Для того чтобы распределять задачи целесообразно использовать клиент-серверную архитектуру. Поэтому мы выбрали для работы операционную систему Linux, язык программирования C++.
Для работы со списком задач была выбрана СУБД MySQL, т.к. Ее уже использует СОВА, и РСК как ее служба тоже будет использовать MySQL. С базой данных из приложения мы будем работать с помощью разработанной библиотеки языка С/C++ libmysql (mysql.h, myglobal.h и другие)
Задача, которую получают клиенты содержит: ссылку на файл для обработки и параметры его кодирования. По полученной ссылке файл будет скачан с существующего FTP сервера кафедры. Для решения этой задачи мы использовали библиотеку языка С/C++: libcurl. Также мы будем использовать эти библиотеки при загрузке уже закодированного видео обратно на FTP сервер СОВЫ.
Кодирование будет осуществлять shell скрипт запускаемый из клиент-приложение. Разработка самого скрипта не входит в мое тз, однако я должен обеспечить его исполнение на этапе кодирования видео.
Забирает из конфигурационного файла параметры для: налаживания клиент-серверного соединения (порт соединения), параметры соединения с базой данных задач кодирования: адрес, логин, пароль, порт пользователя СУБД MySQL. Для этого открываем конфигурационный файл. Каждый параметр помечен конструкцией типа ***имя_параметра. Это сделано чтобы впоследствии было легко разобратся где какие параметры
config = fopen("server.conf", "r")
do {
non_infiniti++; // подстраховка, чтобы цикл не ушел в вечную петлю если не окажется корректного // подтверждения конца файла
fgets(buf, FILELINE, config);
// берем из конфига порт
if( strcmp(buf, "***port\n") == 0 ) {
fgets(buf, FILELINE, config);
SERV_PORT = atoi(buf);
continue; }
......
} while (non_infiniti < 1000);
Соединение с базой данных из которой мы будем получать задачи:
инициация структуры базы данных, если нет необходимых библиотек произойдет ошибка
rskdb = mysql_init(NULL);
непосредственно соединение с базой данных по параметрам, полученным из конфига
mysql_real_connect(rskdb, mysql_host, mysql_user, mysql_pass, mysql_db, mysql_port, NULL, 0 )
Запускает прослушивающий сокет, ожидающий присоединения клиентов-кодировщиков.
Это происходит путем выхова трех комманд:
1) создания интернет сокета fdserver = socket(AF_INET, SOCK_STREAM, 0)
AF_INET означает что мы исползуем протокол IPv4
SOCK_STREAM – используется транспортный протокол TCP , а не UDP (DATAGRAM)
2) bind( fdserver, (struct sockaddr *) &servaddr, sizeof(servaddr))
3) listen(fdserver, 1024)
При присоединении клиента, совершает опрос базы данных задач на предмет наличиия задач кодирования.
Command = = "SELECT * FROM goal WHERE at_work = 0";
mysql_query((MYSQL *)rskdb, command);
Если таковые полученны он забирает задачу из бд на кодирование, отправляет ее клиенты, и ожидает результата работы клиенты – флаг успешного окончания, не успеха выполнения задачи. С помощью этого можно определить корректность выполнения задач клиентами-кодировщиками.
table = mysql_store_result((MYSQL *)rskdb);
if(table == NULL) {
printf("Error: can't get the result description\n");
send(fdclient, "exit", MAXLINE, 0);
break; }
if(mysql_num_rows(table) > 0) {
row = mysql_fetch_row(table);
sendlink = row[1];
sendname = row[3];
Оттданые задачи отмечаем, для того чтобы не раздать на кодирование одни и тежи файлы
mysql_query((MYSQL *)rskdb, UPDATE rsk.goal g SET at_work = 1 WHERE link “sendlink”);
send(fdclient, sendname, MAXLINE, 0);
send(fdclient, sendlink, MAXLINE, 0);
Если задачи кончились – клиенты отсылается флаг успешного окончания работы.
send(fdclient, "exit", MAXLINE, 0);
Забирает из конфигурационного файла пармаетры: соединения с сервером (адрес и порт сервера); соединения с FTP севером (логин пароль).
Коннектится к серверу.
fdclient = socket (AF_INET, SOCK_STREAM, 0);
connect(fdclient, (struct sockaddr *) &servaddr, sizeof(servaddr);
Планируется что кодирующий скрипт будет также скачеватся с ftp сервера, это позволит облегчить вопрос обновления системы – один раз изменив кодирующий скрипт на серверы, все клиенты будут сами обновлятся. Поэтому выполним команду выдачи прав на исполнение нашего кодирующего bash-скрипта.
system( “cmod +x SCRIPT “);
Получает от сервера задачу кодирования.
recv(fdclient, recvflag, MAXLINE, 0);
recv(fdclient, recvlink, MAXLINE, 0);
Обрабатывает задачу:
curl_easy_setopt(curl, CURLOPT_URL, recvlink);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
system("./ SCRIPT recvname newname MYTMP encode_threads ");
curl = curl_easy_init();
curl_easy_setopt(curl,CURLOPT_URL, "ftp:// ftp_login:ftp_pass@ftp_link/newname”);
system("rm recvname");
Это повторяется до тех пор пока не придет флаг что у сервера кончились задачи кодирования.
if( strcmp(recvflag, "exit") == 0) {
send(fdclient, "exit", MAXLINE, 0);
break; }
Написана бэта-версия клиент-серверного приложения.
http://leithal.cool-tools.co.uk/sourcedoc/mysql509/html/mysql_8h.html
http://curl.haxx.se/lxr/source/docs/examples/ftpget.c
http://curl.haxx.se/lxr/source/docs/examples/ftpupload.c
http://www.opennet.ru/docs/RUS/bash_scripting_guide/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <time.h>
#include <errno.h>
#include <mysql.h>
#include <my_global.h>
#define MAXLINE 300
#define FILELINE 200
#define OPT_SIZE 1000
int main()
{
/** take config data **/