Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/68: Рейтинг темы: голосов - 68, средняя оценка - 4.57
2 / 2 / 0
Регистрация: 10.04.2009
Сообщений: 11

Передача файлов TServerSocket TClientSocket

26.04.2009, 13:13. Показов 14068. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Нужно передать файлы по сети через TServerSocket, TClientSocket. Сделал на 6 Builder'e как написано в статье http://devoid.com.ua/c-builder... ocket.html все работало нормально.
Написал подобную на 2009 C++ Builder'e, пришлось немного переделать из-за некорректной работы функций SendText-ReceiveText, и теперь не передает.

Код сервера:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void __fastcall TFormMain::btnSendClick(TObject *Sender)
{
    void *Ptr; // Указатель на файл
    int iSize; // Размер переданного пакета
    AnsiString Str; // Посылаемая строка
 
    if (OpenDialog1->Execute())
    {
        MS->LoadFromFile(OpenDialog1->FileName);
        mmoLog->Lines->Add("Загрузили файл '" + ExtractFileName(OpenDialog1->FileName) + "' в поток...");
        
        // Отправляем заголовок
    Str = "file#" + OpenDialog1->FileName + "#" + IntToStr(MS->Size) + "#";
    ServerSocket1->Socket->Connections[0]->SendBuf(Str.c_str(), Str.Length() + 1);
 
    mmoLog->Lines->Add("Послали заголовок: file#" + OpenDialog1->FileName + "#" + IntToStr(MS->Size) + "#");
    MS->Position = 0; // Устанавливаем поток в начальную позицию
    Ptr = MS->Memory; // Присваиваем указателю поток файла
    // Отправляем буфер клиенту. Size - размер отправленной информации
    iSize = ServerSocket1->Socket->Connections[0]->SendBuf(Ptr, MS->Size);
    mmoLog->Lines->Add("Отправлено " + IntToStr(iSize) + " из " + IntToStr(MS->Size) + "байт"); // Заполняем лог
    }
}
Код клиента:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//---------------------------------------------------
// Глобальные переменные
// Создаем поток под принимаемый файл
TMemoryStream *MS = new TMemoryStream;
// Функция записи принимаемого потока в файл
void Write(AnsiString Text);
// Размер передаваемого файла
int iSize;
// Флаг идентификации передачи файла на данный момент
bool Receive;
// Имя файла
AnsiString FileName;
//---------------------------------------------------
void Write(AnsiString Text)
{
    // Если мы еще принимаем файл и размер потока меньше размера файла
    if (MS->Size < iSize)
    {
        MS->Write(Text.c_str(), Text.Length()); // Записываем в поток
        FormMain->mmoLog->Lines->Add("Принимаем данные..." + IntToStr(MS->Size)); // Пишем лог
    }
    // Если файл принят, и размер потока соответствует размеру файла
    if (MS->Size == iSize)
    {
    ShowMessage("Приняли!");
        Receive = false; // Останавливаем режим передачи файла
        MS->Position = 0; // Переводим каретку потока в начало
        FormMain->ClientSocket1->Socket->SendText("end"); // Пишем серверу что мы приняли файл
        MS->SaveToFile(FileName); // Сохраняем наш файл
        MS->Clear(); // Освобождаем поток
        iSize = 0; // Зануляем переменную
        FormMain->mmoLog->Lines->Add("Файл принят!"); // Пишем в лог, что файл принят
    }
}
//----------------------------------------------------
void __fastcall TFormMain::ClientSocket1Read(TObject *Sender, TCustomWinSocket *Socket)
{
    AnsiString Rtext; // Текст, который посылаем
    int iBufSize = ClientSocket1->Socket->ReceiveLength(); // Размер принимаемого буфера
    char *Buf = new char [iBufSize + 1];
 
    ClientSocket1->Socket->ReceiveBuf(Buf, iBufSize);
    Rtext = AnsiString(Buf);
 
    // Если мы в режиме передачи файла, то
    if (Receive == true)
    {
        Write(Rtext); // Записываем его в поток
    }
    else // если нет, то
    {
        mmoLog->Lines->Add("Приняли текст: " + Rtext); // Пишем в лог все, что принимаем от сервера
        // Если это строка типа file#filename#filesize, то начинаем обрабатывать полученную информацию
        if (Rtext.SubString(0, Rtext.Pos("#") - 1) == "file")
        {
            Rtext.Delete(1, Rtext.Pos("#")); // Удаляем слово file
            Name = Rtext.SubString(0, Rtext.Pos("#") - 1); // Определяем имя файла
            // Выделяем чистое имя файла
            FileName = Name.SubString(Name.LastDelimiter("\\") + 1, Name.Length());
            Rtext.Delete(1, Rtext.Pos("#")); // Удаляем последний разделитель
            iSize = StrToInt(Rtext.SubString(0, Rtext.Pos("#") - 1)); // Определяем размер файла
            Rtext.Delete(1, Rtext.Pos("#")); // Удаляем последний разделитель
            mmoLog->Lines->Add("Размер файла: " + IntToStr(iSize)); // Выводим размер файла в лог
            mmoLog->Lines->Add("Имя файла: " + FileName); // Выводим имя файла в лог
            Receive = true; // Переводим клиент в режим приема файла
        }
    }
}
Файлы больше чем 1Кб не передает.
Где ошибка? Не могу разобраться.
Или может посоветуете другой вариант с использованием этих компонентов.
Только не абстрагируйте сильно. Чтоб на примере было все понятно.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.04.2009, 13:13
Ответы с готовыми решениями:

Передача файлов через TClientSocket и TServerSocket
клиент //cs - ClientSocket //od - OpenDialog void __fastcall TForm1::Button1Click(TObject *Sender) { cs-&gt;Address =...

Передача файлов в C++Builder через TClientSocket и TServerSocket
Всем привет. Есть задача, передать файл от клиента к серверу. Пример программы передачи файлов сервер-клиент нарыл тут ...

Передача файлов между клиентами через TClientSocket и TServerSocket
Добрый вечер! Создаю чат в C++ Builder 6. Несколько дней не могу разобраться, перерыл уже всю информацию в инете и не могу понять, как...

10
 Аватар для FreeWay
84 / 84 / 19
Регистрация: 17.12.2007
Сообщений: 574
27.04.2009, 20:12
где то уже такое было, не помню откуда взял - вот рабочий исходник
Вложения
Тип файла: rar !!.rar (92.7 Кб, 801 просмотров)
0
2 / 2 / 0
Регистрация: 10.04.2009
Сообщений: 11
28.04.2009, 00:08  [ТС]
Цитата Сообщение от FreeWay Посмотреть сообщение
где то уже такое было
Согласен, подобная тема подымалась не раз, но нормального ответа так и не нашел.

не помню откуда взял - вот рабочий исходник
Именно этот пример я и изменял. Этот исходник к статье в 1 посте. Он отлично работает на 6 builder'е. А вот на 2009 из-за некорректной работы функций SendText и ReceiveText его пришлось переделать. Только вот теперь собака, отказывается нормально работать.
0
1090 / 588 / 121
Регистрация: 11.11.2008
Сообщений: 1,544
28.04.2009, 05:58
Цитата Сообщение от Cl3r1k Посмотреть сообщение
на 2009 из-за некорректной работы функций SendText и ReceiveText его пришлось переделать.
ты сам себе овтетил, в 2006 и 2009 багов хватает. я до сих пор сижу на 6 и не жалею, чувствую себя уверенно. по-маленьку паралелльно пытаюсь освоиться в 2006. но вот с тем же Indy10 работать вообще невозможно, продолжаю работать с Indy9. не сомневаюсь что и с остальными компонентами есть проблемы, возможно что и скрытые до определенного времени, но неохота наткнуться на них в какой-нибудь ответственный момент.
0
2 / 2 / 0
Регистрация: 10.04.2009
Сообщений: 11
28.04.2009, 09:20  [ТС]
Цитата Сообщение от AntonChik Посмотреть сообщение
ты сам себе овтетил, в 2006 и 2009 багов хватает. я до сих пор сижу на 6 и не жалею, чувствую себя уверенно. по-маленьку паралелльно пытаюсь освоиться в 2006. но вот с тем же Indy10 работать вообще невозможно, продолжаю работать с Indy9. не сомневаюсь что и с остальными компонентами есть проблемы, возможно что и скрытые до определенного времени, но неохота наткнуться на них в какой-нибудь ответственный момент.
Согласен, багов в 2009 хватает. Неизвестно, сколько еще подводных камней вылезет.
НО:
Во-первых, у меня уже весь проект написан на 2009. И переписывать все под 6 builder будет накладно.
Во-вторых, уж слишком устарел 6 builder. И все компоненты у меня под 2009.
Ну и в-третьих, рано или поздно прийдется переходить на 2009. Я считаю, что лучше раньше чем позже, чтобы потом не оказаться в сложной ситуации.

P.S. Но все же спасибо за мнение. Приму к сведению.
0
 Аватар для FreeWay
84 / 84 / 19
Регистрация: 17.12.2007
Сообщений: 574
30.04.2009, 09:41
аналогично пишу сложные проекты на 6 билдере, там все проверено и изучено, а на 2009 так, мелочь пишу.
Во-вторых, уж слишком устарел 6 builder. - Не знаю как он там устарел, главное чтоб поставленные задачи решал, плюс к тому же если в 6 поставить такие суперовские компоненты как EhLib, Raize, и др., то можно написать более гибкое и симпатичное приолжение)
0
2 / 2 / 0
Регистрация: 10.04.2009
Сообщений: 11
02.05.2009, 17:35  [ТС]
Да просто взялся все проекты под 2009. Так что отложим в сторону идею о написании на 6 builder'е.
Так что по поводу вопроса?
0
 Аватар для QenT
40 / 40 / 8
Регистрация: 29.01.2009
Сообщений: 244
08.05.2009, 04:43
Цитата Сообщение от Cl3r1k Посмотреть сообщение
Файлы больше чем 1Кб не передает.
У тебя передался и сохранился файл!?
Если по коду, то(в 2009) у тебя и 1кб не должен передаться, точнее он то передастся(может быть и весь), но ты его точно не сохранишь! Я прав?
0
2 / 2 / 0
Регистрация: 10.04.2009
Сообщений: 11
08.05.2009, 13:53  [ТС]
Цитата Сообщение от QenT Посмотреть сообщение
Я прав?
Отчасти. Максимальный размер передаваемого файла - 12 843 байт, но это только текстовый файл. Что до бинарных, то даже 1 байт не принимается. Сейчас доделаю другой проект и плотно займусь передачей файлов.
0
 Аватар для QenT
40 / 40 / 8
Регистрация: 29.01.2009
Сообщений: 244
09.05.2009, 02:18
Цитата Сообщение от Cl3r1k Посмотреть сообщение
Отчасти. Максимальный размер передаваемого файла - 12 843 байт, но это только текстовый файл. Что до бинарных, то даже 1 байт не принимается. Сейчас доделаю другой проект и плотно займусь передачей файлов.
Ты за раз отправляешь два сообщения,в итоге когда они приходят к клиенту, часть второго сообщения попадает в первое(у тебя есть вывод первого сообщения на экран, мог бы заметить), из-за этого не могу понять как у тебя совпало, число принятого и отправленного(а ведь сохраннение может быть только при этом условии), предлагаю серверу отправить шляпу, клиент когда получит её, отправит сообщение на согласие, после чего сервер отсылает файл, а клиент уже его ждет...
Если ужь у тебя работает, хотя стоит не видимое ограниечение на размер и вид информации, присмотрись сколько раз ты полученое сообщение переводишь из одного типа в другой и наоборот(уверять не стану, но замечу, что char когда отсылает текс, он его ограничивает '\0' и его легко можно приравнять к AnsiString, а вот когда информация бинарная, её можно ограничить только размером который передается вместе с сообщением в ReceiveBuf(если приравнять простым образом к стрингу, есть шанс появления лишнего хвоста))! Этот исходник в 2009, я уже переделывал до рабочего, с небольшой шалостью, даже мог воровать у клиент "снимок экрана"(если, не уменьшать палитру, весит больше 5Мб). Старался расписать все и доступно, для примера, скину часть своего кода(здесь же приблизил к твоему примеру, могут быть помарки).
Код сервера:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void __fastcall TForm1::SendClick(TObject *Sender)
{
if( OpenDialog1->Execute() )
{
    MSS->LoadFromFile( OpenDialog1->FileName ); // выбираем  файл
    Memo2->Lines->Add( "Загрузили требуемый файл в поток..." ); // заполняем лог
}
AnsiString mess="file#" + OpenDialog1->FileName + "#" + IntToStr( MSS->Size ) + "#";
Server->Socket->Connections[0]->SendText(mess ); // отправляем заголовок
Memo2->Lines->Add ( "Послали заголовок"+mess );
MSS->Position = 0 ;      // Устанавливаем поток в начальную позицию ;
P    = MSS->Memory ;     // присваиваем указателю поток файла
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerClientRead(TObject *Sender, TCustomWinSocket *Socket)
{
int iBufSize = Socket->ReceiveLength();
    // Переменная для приема буфера
char *Buf = new char [iBufSize + 1];
Socket->ReceiveBuf(Buf,iBufSize);
AnsiString Rtext=Buf;
if(Rtext=="end") // если клиент прислал команду "end"
{
    Memo1->Lines->Add("Клиент принял файл"); // записываем в лог
    MSS->Clear() ;                            // Очищаем поток
}
if(Rtext=="Yes") // если клиент прислал команду "Yes"
{
Sizes = Server->Socket->Connections[0]->SendBuf( P , MSS->Size ); // отправляем буфер клиенту; 
                        //равно размеру отправленной  информации
Memo2->Lines->Add( "Отправлено: " + IntToStr( Sizes ) + " из " + IntToStr( MSS->Size ) ); // заполняем лог
}
}
Код клиента:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
void Write( char *Text, int size )
{
    if(MS->Size < Size)  // если мы еще принимаем файл и размер потока меньше размера файла
    {
        MS->Write( Text, size );         // записываем в поток
        Form1->Memo1->Lines->Add( "Принимаем данные("+IntToStr(MS->Size)+")..." ); // пишем лог
    }
    if(MS->Size == Size) // если файл принят и размер потока соответствует размеру файла
    {
        
        Receive = false ;                         // останавливаем режим передачи
        MS->Position = 0 ;      // переводим каретку потока в начало
        Form1->Client->Socket->SendText( "end" ); // пишем серверу, что мы приняли файл
        CreateDir( "Downloads" );                 // создаем папку для сохраненных файлов
        MS->SaveToFile( "Downloads\\"+FileName ); // сохраняем туда наш файл
        MS->Clear() ;                             // освобождаем поток
        Size = 0 ;
        Form1->Memo1->Lines->Add("Файл принят !"); // пишем в лог что файл принят
    }
}
void __fastcall TForm1::ClientRead(TObject *Sender, TCustomWinSocket *Socket)
{
    int iBufSize = Socket->ReceiveLength();
    char *Buf = new char [iBufSize + 1];
    Socket->ReceiveBuf(Buf,iBufSize);
    AnsiString Rtext=Buf;
    if( Receive == true ) // если мы в режиме передачи файла, то
    {
        Write(Buf,iBufSize); // записываем его в поток
    }
    else // если нет , то
    {
        Memo1->Lines->Add( "Приняли текст :" + Rtext );    // пишем в лог все что принимаем от сервера
        if(Rtext.SubString( 0,Rtext.Pos("#")-1) == "file" ) // Если это строка типа
                                                                         // file#filename#filesize#, то начинаем парсерить полученную информацию :
        {
            Rtext.Delete( 1 , Rtext.Pos( "#" ) ) ;            // удаляем слово file
            Name = Rtext.SubString( 0 , Rtext.Pos( "#" ) -1 );// Определяем имя файла
            FileName = Name.SubString( Name.LastDelimiter( "\\" ) + 1 , Name.Length() );
            // Выделяем чистое имя файла , например с c:\\test.txt , берем test.txt
            Rtext.Delete( 1 , Rtext.Pos( "#" ) );                               // Удаляем последний разделитель
            Size = StrToInt( Rtext.SubString( 0 , Rtext.Pos( "#" ) - 1) ) ;     // Определяем размер файла
            Rtext.Delete( 1 , Rtext.Pos( "#" ) );                               // Удаляем последний разделитель
            Memo1->Lines->Add( "Размер файла: " + IntToStr( Size ) + " байт" ); // Выводим размер файла в лог
            Memo1->Lines->Add( "Имя файла: " + Name );                          // Выводим имя файла в лог
            Receive = true;
            Socket->SendText("Yes"+'\0'); Memo1->Lines->Add("Отправили согласие...");// Переводим сервер в режим приёма файла
        }
    }
}
0
0 / 0 / 0
Регистрация: 24.05.2012
Сообщений: 8
08.06.2012, 06:45
Цитата Сообщение от FreeWay Посмотреть сообщение
если в 6 поставить такие суперовские компоненты как EhLib, Raize, и др., то можно написать более гибкое и симпатичное приолжение)
хм.. поделитесь пожалуйста =D

P.S. у меня проблема возникла - клиент сервер на сокетах вроде работает нормально НО, почему то клиент отказывается передавать данные на сервер. Писал шоуМессадж на событие отправки так вот его нет! =( не могу понять почему событие не срабатывает ClientSocket->Socket->SendBuf(&slist,sizeof(slist)); не отправляет на сервер.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.06.2012, 06:45
Помогаю со студенческими работами здесь

Передача файлов TserverSocket
Собственно, организовала передачу файлов через поток TFileStream с использованием компонентов TServerSocket, TClientSocket Суть проблемы:...

TClientSocket и TServerSocket
Не понимаю один вопрос. Например я передаю массив размерностью 4 с одного из этих компонента на другой, т.е. из одного узла в другой, и...

TClientSocket и TServerSocket
У меня вопрос по неопытности, не могу разобраться... Дело в следующем. Пишу приложение (в Borland Developer Studio 2006) которое является...

TServerSocket TClientSocket
пишу программу для мнгновенной отправки сообщений написал 2 программы(клиент и сервер) в клиенте в TClientSocket в свойстве Address...

TClientSocket и TServerSocket
В C++ Builder 6 есть компоненты TClientSocket и TServerSocket, но они предназначены для локальной сети, насколько я понял, а есть что-то...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru