Распределенная служба кодирования

Московский Государственный Институт Электроники и Математеки

кафедра ИКТ







Курсовая работа по предмету:

Сетевые технологии.

Тема работы:

Распределенная служба кодирования



Выполнил

студент группы С-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, "***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 )



Запускает прослушивающий сокет, ожидающий присоединения клиентов-кодировщиков.

Это происходит путем выхова трех комманд:

создания интернет сокета fdserver = socket(AF_INET, SOCK_STREAM, 0)

AF_INET означает что мы исползуем протокол IPv4

SOCK_STREAM – используется транспортный протокол TCP , а не UDP (DATAGRAM)

bind( fdserver, (struct sockaddr *) &servaddr, sizeof(servaddr))

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

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 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; 

} 



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 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; 

} 

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 */; 





16