Главная      Учебники - Разные     Лекции (разные) - часть 19

 

Поиск            

 

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

 

             

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

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

кафедра ИКТ

по предмету:

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

Тема работы:

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

Выполнил

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

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

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

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

Обрабатывает задачу:

  1. По полученной ссылке загружает с FTP сервера файл для кодирования

curl_easy_setopt(curl, CURLOPT_URL, recvlink);

curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);

  1. Запускает кодирующий скрипт

system("./ SCRIPT recvname newname MYTMP encode_threads ");

  1. Загружает закодированный файл на FTP сервер.

curl = curl_easy_init();

curl_easy_setopt(curl,CURLOPT_URL, "ftp:// ftp_login:ftp_pass@ftp_link/newname”);

  1. Удаляет временные файлы.

system("rm recvname");


Это повторяется до тех пор пока не придет флаг что у сервера кончились задачи кодирования.

if( strcmp(recvflag, "exit") == 0) {

send(fdclient, "exit", MAXLINE, 0);

break; }

Заключение

Написана бэта-версия клиент-серверного приложения.

В ней реализованы:

  1. Соединиение клиента и сервера;
  2. Работа клиента с тестовой базой данных;
  3. Пересылка задач от сервера к клиенту, и ответ клиента о степени выполнения задачи (успешно не успешно, как каком этапе произошла ошибка (загрузка, кодирование, выгрузка));
  4. Скачивание и закачивание с FTP сервера файлов;
  5. Имеется тестовый кодирующий скрипт, получающий все необходимые параметры, которые будут в дальнейшем использованы.

Требуется реализовать:

  1. Перенести на реальную базу данных задач. Не выполнено так как мне еще не дали к ней доступ.
  2. Обеспечить коннект к нестандартному порту FTP сервера. Не выполнено, т.к. Этого не было в тз.
  3. Написать кодирующий скрипт. Не выполнено, т.к. Это следующий этап работы.

Использованные источники

  1. Стивенс У.Р. “Unix Разработка сетевых приложений” 2003г.
  2. Руководство по работе с библиотеками libmysql

http://leithal.cool-tools.co.uk/sourcedoc/mysql509/html/mysql_8h.html

  1. Пример использования библиотек libcurl (скачивание)

http://curl.haxx.se/lxr/source/docs/examples/ftpget.c

  1. Пример использования библиотек libcurl (загрузка)

http://curl.haxx.se/lxr/source/docs/examples/ftpupload.c

  1. Руководство по написанию 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 */;