Московский Государственный Институт Электроники и Математеки
кафедра ИКТ
Курсовая работа по предмету:
Сетевые технологии.
Тема работы:
Распределенная служба кодирования
Выполнил
студент группы С-64
Белехов В
Принял
Орлов Петр
Москва 2009 год
Список исполнителей
Белехов Владимир Николаевич – Выполнял работу.
Андреев Дмитрий Рубенович – Подготовил постановку задачи и техническое задание.
Сагратян Асатур Ашаотович – Помощь, google.
Реферат
Ключевые слова:
Распределеный, кодирование, клиент-сервер, база данных.
Приложения:
Листинги: сервер-приложение, клиент-приложение, конфиги к ним, кодирующий скрипт.
Источники: для работы с mysql, libcurl.
Цель работы: Разработать клиент-серверное приложение распределенния задач кодирования.
Методолгия:Научный тык.
Степень внедрения: Отладка.
Область применения: кодирование видео.
Значимость работы: повышает эффективность кодирования видео, сервером СОВА
Оглавление
Список исполнителей
.. 2
Реферат
. 3
Оглавление
. 4
Сокращения
.. 5
Постановка задачи
.. 6
Основная часть
.. 7
Выбор средств разработки
.. 7
Описание работы службы
... 8
Сервер-приложение
. 8
Клиент-приложение
. 10
Заключение
. 12
В ней реализованы:
. 12
Требуется реализовать:
. 12
Использованные источники
.. 13
Приложения
.. 14
Сервер-приложение server.c
. 14
server.conf
. 19
Кодирующий
скрипт
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, "***portn") == 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 descriptionn");
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
http://leithal.cool-tools.co.uk/sourcedoc/mysql509/html/mysql_8h.html
Пример использования библиотек libcurl (скачивание)
http://curl.haxx.se/lxr/source/docs/examples/ftpget.c
Пример использования библиотек libcurl (загрузка)
http://curl.haxx.se/lxr/source/docs/examples/ftpupload.c
Руководство по написанию bash скриптов
http://www.opennet.ru/docs/RUS/bash_scripting_guide/
Приложения
Сервер-приложение server.c
#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 errorn");
return 1;
}
do
{
non_infiniti++; // подстраховка, чтобы цикл не ушел в вечную петлю
fgets(buf, FILELINE, config);
// берем из конфига порт
if( strcmp(buf, "***portn") == 0 )
{
fgets(buf, FILELINE, config);
SERV_PORT = atoi(buf);
continue;
}
if( strcmp(buf, "***mysql_hostn") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &mysql_host[0], buf, buf_len - 1);
continue;
}
if( strcmp(buf, "***mysql_usern") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &mysql_user[0], buf, buf_len - 1);
continue;
}
if( strcmp(buf, "***mysql_passn") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &mysql_pass[0], buf, buf_len - 1);
continue;
}
if( strcmp(buf, "***mysql_databasen") == 0 )
{
fgets(buf, FILELINE, config);
buf_len = strlen(buf);
strncpy( &mysql_db[0], buf, buf_len - 1);
continue;
}
if( strcmp(buf, "***mysql_portn") == 0 )
{
fgets(buf, FILELINE, config);
mysql_port = atoi(buf);
continue;
}
if ( strcmp(buf, "***endn") == 0)
break;
strcpy(buf, "");
} while (non_infiniti < 1000);
printf("%sn", mysql_host);
printf("%sn", mysql_user);
printf("%sn", mysql_pass);
printf("%sn", mysql_db);
printf("%dn", 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-descriptorn");
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 %sn",
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 setn");
/** 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 socketn");
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 %snserv port %dn", myaddr, SERV_PORT);
if ( (bind( fdserver, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0)
{
printf("binding errorn");
close(fdserver);
return 1;
}
if ( (listen(fdserver, 1024)) < 0)
{
printf("listening errorn");
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 errorn");
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-queryn");
send(fdclient, "exit", MAXLINE, 0);
break;
}
// Получаем дескриптор результирующей таблицы
table = mysql_store_result((MYSQL *)rskdb);
if(table == NULL)
{
p
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 goaln");
printf("I send this name : %sn", sendname);
send(fdclient, sendname, MAXLINE, 0);
printf("I send this link : %sn", sendlink);
send(fdclient, sendlink, MAXLINE, 0);
}
else
{
send(fdclient, "exit", MAXLINE, 0);
exitflag = 1;
printf("Задачи кончились !!! bingo gl hfn");
break;
}
// Освобождаем память, занятую результирующей таблицей
mysql_free_result(table);
// тут мы сможем узнать удачно завершилось кодирование или нет
recv(fdclient, strrecv, MAXLINE, 0);
printf("client answer %sn", strrecv);
} while (exitflag != 1);
close(fdserver);
exit(0);
}
}
/** end **/
// Закрываем соединение с сервером базы данных
mysql_close(rskdb);
close(fdserver);
return 0;
}
server.conf
***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
Клиент-Приложение client.c
#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 filen", 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 errorn");
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_portn") == 0 )
{
fgets(buf, FILELINE, config);
SERV_PORT = atoi(buf);
continue;
}
if( strcmp(buf, "***serv_addresn") == 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_loginn") == 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_passn") == 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_linkn") == 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_streamsn") == 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, "***endn") == 0)
break;
} while (non_infiniti < 1000);
/*printf("addr %snport %d n", RSK_SERV_ADDR, SERV_PORT);
printf("login %sn",ftp_login);
printf("pass %sn",ftp_pass);
printf("link %sn",ftp_link);
printf("stream %sn",encode_streams);*/
/** connect to server **/
int fdclient;
struct sockaddr_in servaddr;
if ( ( fdclient = socket (AF_INET, SOCK_STREAM, 0) ) < 0 )
{
printf("socketing errorn");
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 errorn");
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 %sn", recvflag);
if( strcmp(recvflag, "exit") == 0)
{
send(fdclient, "exit", MAXLINE, 0);
break;
}
progress = 0;
recv(fdclient, recvname, MAXLINE, 0);
printf("name %sn", 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%sn", recvlink);
/** download **/
printf("nn DOWNLOADING nn");
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 %dn", res);
send(fdclient, "download error error", MAXLINE, 0);
continue;
}
else
progress = 1;
}
if(ftpfile.stream)
fclose(ftpfile.stream); /* close the local file */
/** encoding **/
printf("nn ENCODING nn");
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("nn%snn", command);
system(command);
/** upload **/
printf("nn UPLOADINGnn");
FILE *hd_src;
struct stat file_info;
if(stat(newname, &file_info)) {
printf("Couldnt open '%s': %sn", 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("%snn", 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 %dn", 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;
}
client.conf
***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 */;