Реферат: Распределенная служба кодирования
Московский Государственный Институт Электроники и Математеки
кафедра ИКТ
Курсовая работа по предмету:
Сетевые технологии.
Тема работы:
Распределенная служба кодирования
Выполнил
студент группы С-64
Белехов В
Принял
Орлов Петр
Москва 2009 год
Белехов Владимир Николаевич – Выполнял работу.
Андреев Дмитрий Рубенович – Подготовил постановку задачи и техническое задание.
Сагратян Асатур Ашаотович – Помощь, google.
Ключевые слова:
Распределеный, кодирование, клиент-сервер, база данных.
Приложения:
Листинги: сервер-приложение, клиент-приложение, конфиги к ним, кодирующий скрипт.
Источники: для работы с mysql, libcurl.
Цель работы: Разработать клиент-серверное приложение распределенния задач кодирования.
Методолгия: Научный тык.
Степень внедрения: Отладка.
Область применения: кодирование видео.
Значимость работы: повышает эффективность кодирования видео, сервером СОВА
Список исполнителей… 2
Реферат. 3
Оглавление. 4
Сокращения… 5
Постановка задачи… 6
Основная часть… 7
Выбор средств разработки… 7
Описание работы службы … 8
Сервер-приложение. 8
Клиент-приложение. 10
Заключение. 12
В ней реализованы: . 12
Требуется реализовать: . 12
Использованные источники… 13
Приложения… 14
Сервер-приложение server.c . 14
Кодирующий скрипт encode_script.sh … 19
Клиент-Приложение client.c . 20
client.conf . 26
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);
Обрабатывает задачу:
- По полученной ссылке загружает с FTP сервера файл для кодирования
curl_easy_setopt(curl, CURLOPT_URL, recvlink);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
- Запускает кодирующий скрипт
system("./ SCRIPT recvname newname MYTMP encode_threads ");
- Загружает закодированный файл на FTP сервер.
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; }
Написана бэта-версия клиент-серверного приложения.
- Соединиение клиента и сервера;
- Работа клиента с тестовой базой данных;
- Пересылка задач от сервера к клиенту, и ответ клиента о степени выполнения задачи (успешно не успешно, как каком этапе произошла ошибка (загрузка, кодирование, выгрузка));
- Скачивание и закачивание с FTP сервера файлов;
- Имеется тестовый кодирующий скрипт, получающий все необходимые параметры, которые будут в дальнейшем использованы.
- Перенести на реальную базу данных задач. Не выполнено так как мне еще не дали к ней доступ.
- Обеспечить коннект к нестандартному порту FTP сервера. Не выполнено, т.к. Этого не было в тз.
- Написать кодирующий скрипт. Не выполнено, т.к. Это следующий этап работы.
- Стивенс У.Р. “Unix Разработка сетевых приложений” 2003г.
- Руководство по работе с библиотеками libmysql
leithal.cool-tools.co.uk/sourcedoc/mysql509/html/mysql_8h.html
- Пример использования библиотек libcurl (скачивание)
curl.haxx.se/lxr/source/docs/examples/ftpget.c
- Пример использования библиотек libcurl (загрузка)
curl.haxx.se/lxr/source/docs/examples/ftpupload.c
- Руководство по написанию bash скриптов
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 **/
int SERV_PORT, mysql_port;
char mysql_host[FILELINE] = {}, mysql_user[FILELINE] = {}, mysql_pass[FILELINE] = {}, mysql_db[FILELINE] = {};
FILE *config;
char buf[FILELINE];
int buf_len = 0, non_infiniti = 0;
if ( ( config = fopen(«server.conf», «r») ) == NULL)
{
printf("\«server.conf\» fopen error\n");
return 1;
}
do
{
non_infiniti++; // подстраховка, чтобы цикл не ушел в вечную петлю
fgets(buf, FILELINE, config);
// берем из конфига порт
if( strcmp(buf, "***port\n") == 0 )
{
fgets(buf, FILELINE, config);
SERV_PORT = atoi(buf);
continue;
}
if( strcmp(buf, "***mysql_host\n") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &mysql_host[0], buf, buf_len — 1);
continue;
}
if( strcmp(buf, "***mysql_user\n") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &mysql_user[0], buf, buf_len — 1);
continue;
}
if( strcmp(buf, "***mysql_pass\n") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &mysql_pass[0], buf, buf_len — 1);
continue;
}
if( strcmp(buf, "***mysql_database\n") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &mysql_db[0], buf, buf_len — 1);
continue;
}
if( strcmp(buf, "***mysql_port\n") == 0 )
{
fgets(buf, FILELINE, config);
mysql_port = atoi(buf);
continue;
}
if ( strcmp(buf, "***end\n") == 0)
break;
strcpy(buf, "");
} while (non_infiniti < 1000);
printf("%s\n", mysql_host);
printf("%s\n", mysql_user);
printf("%s\n", mysql_pass);
printf("%s\n", mysql_db);
printf("%d\n", mysql_port);
/** MySQL init **/
// Дескриптор соединения
MYSQL *rskdb;
// Дескриптор результирующей таблицы
MYSQL_RES *table;
// Дескриптор строки
MYSQL_ROW row;
rskdb = mysql_init(NULL);
if(rskdb == NULL)
{
// Если дескриптор не получен — выводим сообщение об ошибке
fprintf(stderr, «Error: can't create MySQL-descriptor\n»);
exit(1);
}
// Подключаемся к серверу
// потом добавим подцепление из конфига
if(!mysql_real_connect(rskdb,
mysql_host,
mysql_user,
mysql_pass,
mysql_db,
mysql_port, //3306,
NULL,
0
))
{
// Если нет возможности установить соединение с сервером
// базы данных выводим сообщение об ошибке
fprintf(stderr,
«Error: can't connect to database %s\n»,
mysql_error(rskdb));
return 1;
}
else
{
// Если соединение успешно установлено выводим фразу — «Success!»
fprintf(stdout, «Success!\n»);
}
// Устанавливаем кодировку соединения, чтобы предотвратить
// искажения русского текста
if(mysql_query((MYSQL *)rskdb, «SET NAMES 'utf8'») != 0)
printf(«Error: can't set character set\n»);
/** creating listen socket **/
int fdserver, fdclient;
socklen_t client_len;
pid_t childpid;
struct sockaddr_in cliaddr, servaddr;
// сокет сервера
if ( (fdserver = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf(«cant make server socket\n»);
return 1;
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
//servaddr.sin_addr.s_addr = inet_pton(AF_INET, RSK_SERV_ADDR, &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT);
char myaddr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &servaddr.sin_addr, myaddr, sizeof(myaddr));
printf(«serv addres %s\nserv port %d\n», myaddr, SERV_PORT);
if ( (bind( fdserver, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0)
{
printf(«binding error\n»);
close(fdserver);
return 1;
}
if ( (listen(fdserver, 1024)) < 0)
{
printf(«listening error\n»);
close(fdserver);
return 1;
}
char strrecv[MAXLINE], *sendflag, *sendname, *sendlink, *command;
char SQL_QUESTION[] = «SELECT * FROM goal WHERE at_work = 0»;
char SQL_UPDATE[] = «UPDATE rsk.goal g SET at_work = 1 WHERE link = \»";
//char *strsend
//strsend = (char *) malloc ( sizeof( char ) * MAXLINE );
command = (char *) malloc ( sizeof( char ) * MAXLINE);
sendflag = (char *) malloc ( sizeof( char ) * MAXLINE);
sendname = (char *) malloc ( sizeof( char ) * MAXLINE);
sendlink = (char *) malloc ( sizeof( char ) * MAXLINE);
for(;;)
{
client_len = sizeof(cliaddr);
if ((fdclient = accept(fdserver, (struct sockaddr *) &cliaddr, &client_len)) < 0)
{
printf(«accepting error\n»);
close(fdserver);
return 1;
}
if ( ( childpid = fork() ) == 0 ) // дочерний процесс
{
/*** child ***/
close(fdserver); // закрываем прослушивающий сокет
/** send encoding script **/
int exitflag = 0;
do
{
// Выполняем SQL-запрос
strcpy(command, SQL_QUESTION);
if( mysql_query((MYSQL *)rskdb, command) != 0)
{
printf(«Error: can't execute SQL-query\n»);
send(fdclient, «exit», MAXLINE, 0);
break;
}
// Получаем дескриптор результирующей таблицы
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];
strcpy(command, SQL_UPDATE); //… "
strcat(command, sendlink); // link
strcat(command, "\""); // "
mysql_query((MYSQL *)rskdb, command);
send(fdclient, «next goal», MAXLINE, 0);
printf(«next goal\n»);
printf(«I send this name: %s\n», sendname);
send(fdclient, sendname, MAXLINE, 0);
printf(«I send this link: %s\n», sendlink);
send(fdclient, sendlink, MAXLINE, 0);
}
else
{
send(fdclient, «exit», MAXLINE, 0);
exitflag = 1;
printf(«Задачи кончились!!! bingo gl hf\n»);
break;
}
// Освобождаем память, занятую результирующей таблицей
mysql_free_result(table);
// тут мы сможем узнать удачно завершилось кодирование или нет
recv(fdclient, strrecv, MAXLINE, 0);
printf(«client answer %s\n», strrecv);
} while (exitflag != 1);
close(fdserver);
exit(0);
}
}
/** end **/
// Закрываем соединение с сервером базы данных
mysql_close(rskdb);
close(fdserver);
return 0;
}
***port
2011
***mysql_host
localhost
***mysql_user
rsk
***mysql_pass
123
***mysql_database
rsk
***mysql_port
3306
***end
Кодирующий скрипт encode_script.sh
#!/bin/bash
# $1 — source file
# $2 — target file
# $3 — tmp file
echo «sourse $1»
echo target $2
echo tmp $3
echo streams $4
cp $1 $3
mv $3 $2
exit
#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 <errno.h>
#include <curl.h>
#include <types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <easy.h>
#define MAXLINE 300
#define FILELINE 200
#define OPT_SIZE 1000
#define SCRIPT «encode_script.sh»
#define MYTMP «tmp_files/tmp»
#define FILETYPE ".mp4"
struct FtpFile {
const char *filename;
FILE *stream;
};
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
struct FtpFile *out=(struct FtpFile *)stream;
if(out && !out->stream) {
/* open file for writing */
out->stream=fopen(out->filename, «wb»);
if(!out->stream)
return -1; /* failure, can't open file to write */
}
return fwrite(buffer, size, nmemb, out->stream);
}
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
/* in real-world cases, this would probably get this data differently
as this fread() stuff is exactly what the library already would do
by default internally */
size_t retcode = fread(ptr, size, nmemb, stream);
fprintf(stderr, "*** We read %d bytes from file\n", retcode);
return retcode;
}
int main()
{
char command[OPT_SIZE];
/** take config data **/
char RSK_SERV_ADDR[INET_ADDRSTRLEN] = {}, ftp_login[FILELINE] = {}, ftp_pass[FILELINE] = {}, ftp_link[FILELINE] = {};
char encode_streams[5] = {};
int SERV_PORT;
FILE *config;
if ( ( config = fopen(«client.conf», «r») ) == NULL)
{
printf("\«client.conf\» fopen error\n");
return 1;
}
char buf[FILELINE];
int buf_len = 0, non_infiniti = 0;
do
{
non_infiniti++; // подстраховка, чтобы цикл не ушел в вечную петлю
strcpy(buf, "");
fgets(buf, FILELINE, config);
// берем из конфига порт
if( strcmp(buf, "***serv_port\n") == 0 )
{
fgets(buf, FILELINE, config);
SERV_PORT = atoi(buf);
continue;
}
if( strcmp(buf, "***serv_addres\n") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &RSK_SERV_ADDR[0], buf, buf_len — 2);
strcat( &RSK_SERV_ADDR[0], "\0");
continue;
}
if( strcmp(buf, "***ftp_login\n") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &ftp_login[0], buf, buf_len — 2);
strcat( &ftp_login[0], "\0");
continue;
}
if( strcmp(buf, "***ftp_pass\n") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &ftp_pass[0], buf, buf_len — 2);
strcat( &ftp_pass[0], "\0");
continue;
}
if( strcmp(buf, "***ftp_link\n") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &ftp_link[0], buf, buf_len — 2);
strcat( &ftp_link[0], "\0");
continue;
}
if( strcmp(buf, "***encode_streams\n") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &encode_streams[0], buf, buf_len — 2);
strcat( &encode_streams[0], "\0");
continue;
}
if ( strcmp(buf, "***end\n") == 0)
break;
} while (non_infiniti < 1000);
/*printf(«addr %s\nport %d \n», RSK_SERV_ADDR, SERV_PORT);
printf(«login %s\n»,ftp_login);
printf(«pass %s\n»,ftp_pass);
printf(«link %s\n»,ftp_link);
printf(«stream %s\n»,encode_streams);*/
/** connect to server **/
int fdclient;
struct sockaddr_in servaddr;
if ( ( fdclient = socket (AF_INET, SOCK_STREAM, 0) ) < 0 )
{
printf(«socketing error\n»);
return 1;
}
bzero( &servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET, RSK_SERV_ADDR, &servaddr.sin_addr);
if ( ( connect(fdclient, (struct sockaddr *) &servaddr, sizeof(servaddr) ) ) < 0 )
{
printf(«connection error\n»);
close(fdclient);
return 1;
}
/** getting encoding script **/
// comming soon
// this summer
// movie «this programm are working»
strcpy( command, «chmod +rx „);
strcat( command, SCRIPT);
system( command);
/** data transfer **/
/* coding progress flag
* 1 — download file
* 2 — encode file
* 3 — upload file */
int progress = 0;
char recvflag[MAXLINE], recvname[MAXLINE], recvlink[MAXLINE];
char newname[MAXLINE];
// char strsend[MAXLINE];
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_DEFAULT);
for(;;)
{
// “exit» or «next step»
recv(fdclient, recvflag, MAXLINE, 0);
printf(«recv flag %s\n», recvflag);
if( strcmp(recvflag, «exit») == 0)
{
send(fdclient, «exit», MAXLINE, 0);
break;
}
progress = 0;
recv(fdclient, recvname, MAXLINE, 0);
printf(«name %s\n», recvname);
// newname — 4 simbols (.avi) + .mpeg4
buf_len = strlen(recvname);
strncpy(newname, recvname, buf_len — 4);
newname[buf_len — 4] = '\0';
//strcat(newname, ".mpeg4");
strcat(newname, FILETYPE);
//printf («NEWNAME = %s[]\n», newname);
recv(fdclient, recvlink, MAXLINE, 0);
printf(«I will download this link:\n%s\n», recvlink);
/** download **/
printf("\n\n DOWNLOADING \n\n");
curl = curl_easy_init();
struct FtpFile ftpfile={
recvname, /* name to store the file as if succesful */
NULL
};
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, recvlink);
/* Define our callback to get called when there's data to be written */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
/* Set a pointer to our struct to pass to the callback */
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
/* Switch on full protocol/debug output */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
if(CURLE_OK != res)
{
/* we failed */
fprintf(stderr, «curl told us %d\n», res);
send(fdclient, «download error error», MAXLINE, 0);
continue;
}
else
progress = 1;
}
if(ftpfile.stream)
fclose(ftpfile.stream); /* close the local file */
/** encoding **/
printf("\n\n ENCODING \n\n");
strcpy(command, "./");
strcat(command, SCRIPT);
strcat(command, " ");
strcat(command, recvname);
strcat(command, " ");
strcat(command, newname);
strcat(command, " ");
strcat(command, MYTMP);
strcat(command, " ");
strcat(command, encode_streams);
// printf("\n\n%s\n\n", command);
system(command);
/** upload **/
printf("\n\n UPLOADING\n\n");
FILE *hd_src;
struct stat file_info;
if(stat(newname, &file_info)) {
printf(«Couldnt open '%s': %s\n», newname, strerror(errno));
send(fdclient, «upload error error», MAXLINE, 0);
continue;
}
hd_src = fopen(newname, «rb»);
/* get a curl handle */
curl = curl_easy_init();
if(curl) {
/* we want to use our own read function */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
/* enable uploading */
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
/* specify target */
strcpy(command, «ftp://»);
strcat(command, ftp_login); //Vladimir.Belekhov
strcat(command, ":"); //:
strcat(command, ftp_pass); // pass
strcat(command, "@"); //@
strcat(command, ftp_link); //share.auditory.ru/2011/Vladimir.Belekhov/test/upload/");
strcat(command, newname); // avi.avi
// printf("%s\n\n", command);
curl_easy_setopt(curl,CURLOPT_URL, command);
/* now specify which file to upload */
curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
/* Now run off and do what you've been told! */
res = curl_easy_perform(curl);
/** curl_ok != res maybe? **/
if(CURLE_OK != res)
{
/* we failed */
fprintf(stderr, «curl told us %d\n», res);
send(fdclient, «upnload error error», MAXLINE, 0);
continue;
}
else
{
progress = 3;
strcpy(command, «rm „);
strcat(command, recvname);
strcat(command, “ „);
strcat(command, newname);
system(command);
}
/* always cleanup */
curl_easy_cleanup(curl);
}
fclose(hd_src); /* close the local file */
// тут мы пошлем серверу результат кодирования (удачный или нет)
send(fdclient, “next goal», MAXLINE, 0);
}
/* завершение работы клиента
*/
curl_global_cleanup();
close(fdclient);
return 0;
}
***serv_port
2011
***serv_addres
0.0.0.0
// gets only first string after flag
10.0.0.140
***ftp_login
***ftp_pass
***ftp_link
share.auditory.ru/2011/Vladimir.Belekhov/test/upload/
***encode_streams
2
***end
MySQL dump тестовой базы данных
— MySQL Administrator dump 1.4
—
— —
— Server version 5.0.51a-24+lenny1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
—
— Create schema rsk
—
CREATE DATABASE IF NOT EXISTS rsk;
USE rsk;
—
— Definition of table `rsk`.`goal`
—
DROP TABLE IF EXISTS `rsk`.`goal`;
CREATE TABLE `rsk`.`goal` (
`id` int(10) unsigned NOT NULL auto_increment,
`link` char(200) character set ucs2 NOT NULL default '0' COMMENT 'links to download files — must send to client',
`at_work` tinyint(1) unsigned NOT NULL default '0' COMMENT '1 when goal already send to client',
`file_name` char(100) NOT NULL COMMENT 'file names кароче чтобы наш curl мог назвать так скачанный файл',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1 COMMENT='stored rsk goals';
—
— Dumping data for table `rsk`.`goal`
—
/*!40000 ALTER TABLE `goal` DISABLE KEYS */;
LOCK TABLES `goal` WRITE;
INSERT INTO `rsk`.`goal` VALUES (1,'http://share.auditory.ru/2011/Vladimir.Belekhov/test/testa.bmp',1,'testa.bmp'),
(2,'http://share.auditory.ru/2011/Vladimir.Belekhov/test/testaa.bmp',1,'testaa.bmp'),
(3,'http://share.auditory.ru/2011/Vladimir.Belekhov/test/testaaa.bmp',1,'testaaa.bmp'),
(4,'http://share.auditory.ru/2011/Vladimir.Belekhov/test/testaaaa.bmp',1,'testaaaa.bmp'),
(5,'http://share.auditory.ru/2011/Vladimir.Belekhov/test/testaaaaa.bmp',1,'testaaaaa.bmp'),
(6,'http://share.auditory.ru/2011/Vladimir.Belekhov/test/testaaaaaa.bmp',1,'testaaaaaa.bmp'),
(7,'http://share.auditory.ru/2011/Vladimir.Belekhov/test/testaaaaaaa.bmp',1,'testaaaaaaa.bmp'),
(8,'http://share.auditory.ru/2011/Vladimir.Belekhov/test/testaaaaaaaa.bmp',1,'testaaaaaaaa.bmp'),
(9,'http://share.auditory.ru/2011/Vladimir.Belekhov/test/testaaaaaaaaa.bmp',1,'testaaaaaaaaa.bmp'),
(10,'http://share.auditory.ru/2011/Vladimir.Belekhov/test/testaaaaaaaaaa.bmp',1,'testaaaaaaaaaa.bmp');
UNLOCK TABLES;
/*!40000 ALTER TABLE `goal` ENABLE KEYS */;
—
— Definition of table `rsk`.`pid`
—
DROP TABLE IF EXISTS `rsk`.`pid`;
CREATE TABLE `rsk`.`pid` (
`pids` int(10) unsigned NOT NULL COMMENT 'child pids',
`at_work` tinyint(1) NOT NULL default '0' COMMENT 'true when server work with client'
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='stored pids parallel servers childs';
—
— Dumping data for table `rsk`.`pid`
—
/*!40000 ALTER TABLE `pid` DISABLE KEYS */;
LOCK TABLES `pid` WRITE;
INSERT INTO `rsk`.`pid` VALUES (1,1);
UNLOCK TABLES;
/*!40000 ALTER TABLE `pid` ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;