Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Передача файла от Клиента к Серверу Сокеты


Автор: aank10 26.9.2012, 17:30
Нашел исходник передачи файлов от сервера к клиенту, все нормально работает, пытаюсь реализовать обратную передачу от клиента к серверу.
Код сервера
Код

TForm1 *Form1;
TMemoryStream *MS = new TMemoryStream ; // создаем поток под принимаемый файл
void Write( AnsiString Text );          // ф-я записи получаемой информации в поток
int Size ;                              // размер передаваемого файла
bool Receive ;                          // передаем ли мы на данный момент файл
AnsiString FileName ;                   //  имя файла
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
void Write( AnsiString Text )
{
    if(MS->Size < Size)  // если мы еще принимаем файл и размер потока меньше размера файла
    {
        MS->Write( Text.c_str() , Text.Length() );         // записываем в поток
        
    }
    if(MS->Size == Size) // если файл принят и размер потока соответствует размеру файла
    {
        Receive = false ;                         // останавливаем режим передачи
        MS->Position = 0 ;                        // переводим каретку потока в начало
        Form1->ServerSocket1->Socket->SendText( "end" ); // пишем серверу, что мы приняли файл
        CreateDir( "Downloads" );                 // создаем папку для сохраненных файлов
        MS->SaveToFile( "Downloads\\"+FileName ); // сохраняем туда наш файл
        MS->Clear() ;                             // освобождаем поток
        Size = 0 ;

    }
}
//---------------------------------------------------------------------------


void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
      TCustomWinSocket *Socket)
{
AnsiString Rtext ;  // текст, который посылает сервер
    Rtext = ServerSocket1->Socket->ReceiveText() ;
    if( Receive == true ) // если мы в режиме передачи файла, то
    {
        Write( Rtext ); // записываем его в поток
    }
    else // если нет , то
    {

        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( "#" ) );                               // Удаляем последний разделитель

            Receive = true;
            // Переводим сервер в режим приёма файла

        }
    }
}



Код клиента

Код


//---------------------------------------------------------------------------

#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::Button1Click(TObject *Sender)
{

void *P;   // указатель на файл
int Size; // размер
if( OpenDialog1->Execute() )
{
    MS->LoadFromFile( OpenDialog1->FileName ); // выбираем  файл
    Memo1->Lines->Add( "Загрузили требуемый файл в поток..." ); // заполняем лог 
}

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

}





Но передача почему то не работает, клиент выбивает "asynchronous socket error 10053 " и "Windows sicket error : удаленный хост принудительно разорвал существующее подключение 10054 on api 'Send' "
А сервер выбивает такую ошибку "Windows sicket error : Запрос на отправку или получение данных no adress was supplied (10057), on API 'recv' "

Погуглив узнал что косяк с размером памяти.

З.Ы. Или если есть дайте свой код где идет передача ОТ Клиента К Серверу.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)