Лена |
Отправлено: 31.05.2005, 12:12 |
|
Не зарегистрирован
|
Кто знает, приведите пример, как пересылать файламы при сети на основе компонетов Indy с вкладки Builder. Пример пожалуйста. Спасибо. |
|
Gedeon |
Отправлено: 31.05.2005, 12:50 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Какой конкретно протокол Вас интересует?
|
|
Лена |
Отправлено: 31.05.2005, 13:53 |
|
Не зарегистрирован
|
Меня интересует возможность пересылки двоичных файлов в локальной сети при помощи компонентов IdTCPServer1 и IdTCPClient.
Клиентское приложение отправляет файл из OpenDialog, сервер принимает и рассылает другим компьютерам локальной сети. Пока у меня не получается, и в Интернете работающих примеров не нашла.
Заранее спасибо.
|
|
Лена |
Отправлено: 31.05.2005, 14:20 |
|
Не зарегистрирован
|
Я так предпологаю, что отсылка из клиента будет выглядеть так:
if(OpenDialog1->Execute())
{
IdTCPClient1->Connect();
IdTCPClient1->WriteFile(OpenDialog1->FileName);
IdTCPClient1->Disconnect();
}
А как прием на сервер организовать для дальнейшей пересылки этого файла другим клиентам? |
|
Gedeon |
Отправлено: 31.05.2005, 15:21 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Я тут чуть-чуть покопался, вот что получилось, на форме клиент и сервер, айпи 127.0.0.1 порты есс-но одинаковые
CODE |
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TFileStream *f = new TFileStream("c:\\iexplore.exe",fmOpenRead);
IdTCPClient1->Connect();
IdTCPClient1->OpenWriteBuffer();
IdTCPClient1->WriteStream(f,true,true);
IdTCPClient1->CloseWriteBuffer();
delete f;
IdTCPClient1->Disconnect();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Execute(TIdPeerThread *AThread)
{
TFileStream *f = new TFileStream("c:\\ie.exe",fmOpenWrite);
AThread->Connection->ReadStream(f,-1,true);
delete f;
}
//--------------------------------------------------------------------------- |
копируетяся ие нормально, только впереди 4 левых символа, я их удалял в фаре, и после этого эксплорер отлично запускался, дальше ковырять нет времени, пытайтесь разобраться сами или кто еще поможет.
З.Ы. Файл должен существовать на сервере, но его ведь не трудно создать, передав перед фалом его название с пом. WriteLn
Отредактировано Gedeon — 31/05/2005, 15:24
|
|
Gedeon |
Отправлено: 31.05.2005, 15:45 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Я понял что это за 4 байта — это размер потока, передаваемый в инт.
чтоб этого не было поправьте строку передачи
CODE |
IdTCPClient1->WriteStream(f,true,false); |
Проверил передачу на соседний ящик, работает.
Отредактировано Gedeon — 31/05/2005, 16:00
|
|
Лена |
Отправлено: 31.05.2005, 16:15 |
|
Не зарегистрирован
|
Огромное Вам спасибо!!! |
|
Лена |
Отправлено: 31.05.2005, 16:30 |
|
Не зарегистрирован
|
Скажите, а если я отправляю этот полученный файл с сервера всем клиентам локальной сети то, как правильно написать отправку? Совокупность слушающих сокетов, используемых сервером, содержится в свойстве Bindings имеющего свойство Items — индексированный массив соединений.
Спасибо.
|
|
Лена |
Отправлено: 31.05.2005, 17:14 |
|
Не зарегистрирован
|
Eще не большой вопрос:
Отправка с именем файла:
if(OpenDialog1->Execute())
{
TFileStream *f = new TFileStream(OpenDialog1->FileName,fmOpenRead);
IdTCPClient1->Connect();
IdTCPClient1->OpenWriteBuffer();
IdTCPClient1->WriteLn(OpenDialog1->FileName);
IdTCPClient1->CloseWriteBuffer();
IdTCPClient1->OpenWriteBuffer();
IdTCPClient1->WriteStream(f,true,false);
IdTCPClient1->CloseWriteBuffer();
delete f;
IdTCPClient1->Disconnect();
}
Прием на сервере:
Для начала получить имя файла и создать его.
AnsiString S = AThread->Connection->ReadLn();
S = S.SubString( S.LastDelimiter( "\\" ) + 1 , S.Length() );
FileCreate("C:\\Dow\\" + S);
Почему то после выполнения этого кода в папке Dow возникает множество мусора ? –(
|
|
Guest |
Отправлено: 31.05.2005, 17:22 |
|
Не зарегистрирован
|
Мимоходом:
Есть удобная функция ExtractFileName и иже с ней. |
|
Gedeon |
Отправлено: 31.05.2005, 19:41 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Вот пример с созданием файла, никакого мусора
CODE |
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(OpenDialog1->Execute()){
IdTCPClient1->Connect();
IdTCPClient1->WriteLn(OpenDialog1->FileName);
TFileStream *f = new TFileStream(OpenDialog1->FileName,fmOpenRead);
//IdTCPClient1->Host = "90.0.0.44";
IdTCPClient1->OpenWriteBuffer();
IdTCPClient1->WriteStream(f,true,true);
IdTCPClient1->CloseWriteBuffer();
delete f;
IdTCPClient1->Disconnect();
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Execute(TIdPeerThread *AThread)
{
AnsiString C_Path = "C:\\1\\" + ExtractFileName(AThread->Connection->ReadLn());
Label2->Caption = C_Path;
if(!FileExists(C_Path)){
FileCreate(C_Path);
}
int size;
size = AThread->Connection->ReadInteger();
Label1->Caption = size;
TFileStream *f = new TFileStream(C_Path,fmOpenWrite);
AThread->Connection->ReadStream(f,-1,true);
delete f;
}
//--------------------------------------------------------------------------- |
так же Вы получаете размер файла, м. использовать для какого-нить прогреса. Если файл существует, он просто переписывается.
Как файл передать от сервера к клиентам в произвольный момент я не могу сообразить, но наверное как-то можно. Я бы просто повесил на каждого клиента по серверу, а на сервер по клиенту само собой порты пар совпадать не должны и потом таким же способом пересылал файлы на клиентов перебирая их айпи, из Bindings, только тогда Вам нужно дисконект с клиента в основном соединении делать только при завершении его работы, а коннект сразу при запуске проги. Ну тут дальше обрабатывайте напильником под свои нужды.
|
|
Лена |
Отправлено: 01.06.2005, 08:06 |
|
Не зарегистрирован
|
Еще раз большое спасибо за помощь!!! |
|
Лена |
Отправлено: 01.06.2005, 15:18 |
|
Не зарегистрирован
|
На строчке TFileStream *f = new TFileStream(C_Path,fmOpenWrite);
возникает исключение, что не может открыть файл C_Path. Проход с точками останова показывает, что в C_Path все нормально записалось, однако на диске папки с этим файлов не появляется, как будто не сработала ф-ция FileCreate.
Gedeon, подскажите, что не так?
|
|
Gedeon |
Отправлено: 01.06.2005, 16:01 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Дык папка уже должна существовать. Или она есть, а файл не создается?
|
|
Лена |
Отправлено: 01.06.2005, 16:15 |
|
Не зарегистрирован
|
1. Создаю папку под именем 6 (код ниже)
2. В момент выполнения приложения на строке
TFileStream *f = new TFileStream(C_Path,fmOpenWrite); возникает исключение Cannot Open file... и программа прерывается.
3. Заглядываю в папку, там нужный файл нулевого размера.
Может это связано с флагом fmOpenWrite? Почему же тогда у Вас работает?
void __fastcall TForm1::IdTCPServer1Execute(TIdPeerThread *AThread)
{
AnsiString C_Path = "C:\\6\\" + ExtractFileName(AThread->Connection->ReadLn());
if(!FileExists(C_Path))
{
FileCreate(C_Path);
}
TFileStream *f = new TFileStream(C_Path,fmOpenWrite);
AThread->Connection->ReadStream(f,-1,true);
delete f;
}
|
|
Gedeon |
Отправлено: 01.06.2005, 17:01 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Поставьте точку останова на эту строку, затем перейдите в фар или че-нить еще и попробуйте открыть файл на редактирование в каком нить редакторе, если откроется закрывайте редактор и продолжайте выполнение программы, если нет надо искать почему, напишите результат этих действий.
|
|
** Лена |
Отправлено: 01.06.2005, 17:29 |
|
Не зарегистрирован
|
Пробую сохранить текстовый файл txt.
1. Ставлю точку останова. Открываю фар, вижу свой файл в папке. Он нулевого размера, жму на нем Enter сначала появляется Блокнот затем выскакиваю окно Windows “Процесс не может получить доступ к файлу, так этот файл занят другим процессом”. Жму ОК. Получаю чистый лист в Блокноте.
2. Пробую при точке останова сначала открыть Блокнот затем файл открыть командой Open Блокнота, получаю сообщение “Процесс не может получить доступ к файлу, так этот файл занят другим процессом”.
Я правельно поняла Ваши инструкции?
|
|
Gedeon |
Отправлено: 01.06.2005, 18:02 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Ну тогда что-то с FileCreate не то, или еще что-то держит файл и не дает его открыть, что возвращает FileCreate? Не может ли кто-то еще открывать только созданный файл? Попробуйте поставить Sleep после создания файла, если он только создался не понятно почему к нему нет доступа, если файл с таким именем уже есть, он не создается, может ли он быть кем-то открыт?
|
|
Лена |
Отправлено: 01.06.2005, 18:19 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Sleep не помогло. Сразу по истечении возникает исключение.
Есть ли замена ф-ции FileCreate? Правда по внешнему виду вроде FileCreate работает — создает файл нулевого размера в нужной папке, вот только почему-то не удается в него записать строкой
TFileStream *f = new TFileStream(C_Path,fmOpenWrite);
|
|
Лена |
Отправлено: 02.06.2005, 08:28 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Попробовала создать полностью новый проект. Все равно возникает исключение на строке записи в файл. |
|
Лена |
Отправлено: 02.06.2005, 08:55 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Ниже код который создает в папке файлы нужного размера:
void __fastcall TForm1::IdTCPServer1Execute(TIdPeerThread *AThread)
{
AnsiString C_Path = "C:\\6\\" + ExtractFileName(AThread->Connection->ReadLn());
int hnd;
if(!FileExists(C_Path))
{
hnd=FileCreate(C_Path);
if(hnd==-1)
{
Application->MessageBox(Не удалось создать...",C_Path.c_str(),MB_ICONEXCLAMATION);
return;
}
FileClose(hnd);
}
TFileStream *f = new TFileStream(C_Path,fmOpenWrite);
AThread->Connection->ReadStream(f,-1,true);
delete f;
}
Однако, например, видео файлы после такой пересылки перестают открываться. |
|
Gedeon |
Отправлено: 02.06.2005, 11:56 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
QUOTE (Лена @ 02/06/2005, 08:55) | Однако, например, видео файлы после такой пересылки перестают открываться. |
Размер оригинала и полученного файла совпадают?
|
|
Лена |
Отправлено: 02.06.2005, 12:32 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Да, размеры совпадают. Однако те видео файлы, которые попали в папку, после пересылки не открываются. Пишет, как обычно бывает про то, что Media Player открыть не может, хотя все оригиналы открываются без проблем.
Это происходит не только с видео. Без проблем открылся файл — pdf, и gif. В файле doc слетела кодировка, файл psd от Фотошопа тоже не открылся, размеры везде совпадают. Может попробовать другую ф-цию записи? У Indy я нашла ф-цию WriteFile, как Вы думаете Gedeon, ее можно использовать или это не то?
|
|
Лена |
Отправлено: 02.06.2005, 12:40 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Eще нашла какую то ф-цию — WriteBuffer |
|
Gedeon |
Отправлено: 02.06.2005, 13:21 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Сравните файлы командой fc в консоли, если разные, то попробуйте другие функции, я не знаю.
|
|
Лена |
Отправлено: 02.06.2005, 14:32 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Ф-ция WriteFile выдает исключение Cannot Open file.
Как правильно сформировать буфер для WriteBuffer и как получить из этого буфера данные в серверном обработчике?
Кто знает вообще, как без проблем и надежно передавать двоичные файлы по локальной сети? У меня не получилось ни через сокеты ни через Indy.
Если кто знает, укажите адрес в Интернете с надежно работающим примером пересылки файлов в локальной сети на С++ Builder 6 please!!!
|
|
Gedeon |
Отправлено: 03.06.2005, 15:13 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Ну, Лена, не знаю что у Вас не получается, у меня все работает, проверял видео файлы ~40 Мб все показывает (мож у Вас кодеков нет на удаленном компе?), вордовские файлы, все у меня работает!
Прикладываю проект, исходники и ехе, проверяйте.
У меня ВСВ 6 апд 4, инди — 8.
|
|
AVC |
Отправлено: 03.06.2005, 15:50 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Хотел попробовать и ...
CODE |
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(OpenDialog1->Execute()){
IdTCPClient1->Host = "90.0.0.44";
Label7->Caption = "Подключение ...";
|
Зачем
У меня под рукой нет ни 6 ни Indi. |
|
Лена |
Отправлено: 03.06.2005, 16:37 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Спасибо за помощь, но есть несколько вопросов:
1. Проект не компилируется пишет “Unable to open file ‘ODENBAKH.LIB’, соответственно я не могу получить новый exe.
2. Прилагаемые exe не могу использовать т.к. жестко в коде прописано dTCPClient1->Host = "90.0.0.44";
3. Что за компонент IdAntiFreeze?
Сейчас я просто буду копировать Ваш код, в свое приложении и сообщу о результатах.
Builder у меня 6 SP 4, ну а версию Indy я не знаю как посмотреть, она стандартная — после установки ничего не менялось.
Еще раз спасибо за помощь.
|
|
Лена |
Отправлено: 03.06.2005, 16:46 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Из Вашего кода поняла как узнать версию — у меня 8.0.25 |
|