//---------------------------------------------------------------------------
#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("Коннектимся...");
}
//---------------------------------------------------------------------------
Размер передаваемых файлов через TSocket
http://devoid.com.ua/c-builder/cppbuilder-network-programming/peredacha-failov-v-c-builder-cherez-socket.html
клиент
сервер
Но есть проблема: файлы большого размера более 5 мб, не пересылаются. То есть сервер вроде отправляет, а клиент до конца не принимает. В чем суть проблемы?
Собрал клиент-сервер на сокетах по примеру
клиент
Код:
сервер
Код:
//---------------------------------------------------------------------------
#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 ) ); // заполняем лог
}
//---------------------------------------------------------------------------
#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 мб, не пересылаются. То есть сервер вроде отправляет, а клиент до конца не принимает. В чем суть проблемы?
Посылай в цикле кусками по несколько килобайт¸ предварительно отправив размер файла, что бы клиент знал когда конец будет.
Или в самом нечале передавайте размер uint'ом.
А вообще, есть функция