Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Размер передаваемых файлов через TSocket

68K
14 марта 2011 года
hobbitivan
6 / / 13.03.2011
Собрал клиент-сервер на сокетах по примеру http://devoid.com.ua/c-builder/cppbuilder-network-programming/peredacha-failov-v-c-builder-cherez-socket.html
клиент
Код:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;  TMemoryStream *MS = new TMemoryStream ; // создаем поток под принимаемый файл
void Write( AnsiString Text );          // ф-я записи получаемой информации в поток
int Size ;                              // размер передаваемого файла
bool Receive ;                          // передаем ли мы на данный момент файл
AnsiString FileName ;
void Write( AnsiString Text )
{
    if(MS->Size < Size)  // если мы еще принимаем файл и размер потока меньше размера файла
    {
        MS->Write( Text.c_str() , Text.Length() );         // записываем в поток
        Form1->Memo1->Lines->Add( "Принимаем данные..." ); // пишем лог
    }
    if(MS->Size == Size) // если файл принят и размер потока соответствует размеру файла
    {
        Receive = false ;                         // останавливаем режим передачи
        MS->Position = 0 ;                        // переводим каретку потока в начало
        Form1->ClientSocket1->Socket->SendText( "end" ); // пишем серверу, что мы приняли файл
        CreateDir( "Downloads" );                 // создаем папку для сохраненных файлов
        MS->SaveToFile( "Downloads\\"+FileName ); // сохраняем туда наш файл
        MS->Clear() ;                             // освобождаем поток
        Size = 0 ;
        Form1->Memo1->Lines->Add("Файл принят !"); // пишем в лог что файл принят
    }
}

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
      TCustomWinSocket *Socket)
{
AnsiString Rtext ;  // текст, который посылает сервер
    Rtext = ClientSocket1->Socket->ReceiveText() ;
    if( Receive == true ) // если мы в режиме передачи файла, то
    {
        Write( Rtext ); // записываем его в поток
    }
    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;
            // Переводим сервер в режим приёма файла
           
        }
    }

}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Connect(TObject *Sender,
      TCustomWinSocket *Socket)
{
Memo1->Lines->Add("Вы подключились");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Error(TObject *Sender,
      TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
ErrorCode = 0;
ShowMessage("Client Error");        
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ClientSocket1->Host = MaskEdit1->Text;
ClientSocket1->Address = MaskEdit1->Text;
ClientSocket1->Open();
Memo1->Lines->Add("Коннектимся...");
}
//---------------------------------------------------------------------------

сервер
Код:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//поток, который мы будем передавать клиенту
TMemoryStream *MS = new TMemoryStream ;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ServerSocket1Accept(TObject *Sender,
      TCustomWinSocket *Socket)
{
Memo1->Lines->Add("К Вам подключились ;");        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ServerSocket1ClientError(TObject *Sender,
      TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
ErrorCode = 0;
ShowMessage("Server Error");
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
ServerSocket1->Active = true;
ServerSocket1->Open();
Memo1->Lines->Add("Создан сервер");


}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
void *P;   // указатель на файл
int Size; // размер
if( OpenDialog1->Execute() )
{
    MS->LoadFromFile( OpenDialog1->FileName ); // выбираем  файл
    Memo1->Lines->Add( "Загрузили требуемый файл в поток..." ); // заполняем лог
}
ServerSocket1->Socket->Connections[0]->SendText( "file#" + OpenDialog1->FileName + "#" + IntToStr( MS->Size ) + "#" );
// отправляем заголовок

Memo1->Lines->Add ( "Послали заголовок" );
MS->Position = 0 ;      // Устанавливаем поток в начальную позицию ;
P    = MS->Memory ;     // присваиваем указателю поток файла
Size = ServerSocket1->Socket->Connections[0]->SendBuf( P , MS->Size );               // отправляем буфер клиенту; Size
                                                                             //равно размеру отправленной  информации
Memo1->Lines->Add( "Отправлено: " + IntToStr( Size ) + " из " + IntToStr( MS->Size ) ); // заполняем лог
}
//---------------------------------------------------------------------------

Но есть проблема: файлы большого размера более 5 мб, не пересылаются. То есть сервер вроде отправляет, а клиент до конца не принимает. В чем суть проблемы?
11
14 марта 2011 года
oxotnik333
2.9K / / 03.08.2007
Посылай в цикле кусками по несколько килобайт&#184; предварительно отправив размер файла, что бы клиент знал когда конец будет.
277
14 марта 2011 года
arrjj
1.7K / / 26.01.2011
Или в самом нечале передавайте размер uint'ом.
278
14 марта 2011 года
Alexander92
1.1K / / 04.08.2008
А вообще, есть функция TransmitFile().
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог