BCB6: Binäre Datei per TClientSocket versenden



  • Hallo Leute,

    ich habe scheinbar ein einfaches Problem, über das ich nicht hinweg komme. *Brett vor dem Kopf hab* Ich arbeite mit dem BCB6 und möchte eine binäre Datei auf einen Apache Webserver hochladen. Dazu verwende ich den TClientSocket.

    Hier ein Auszug aus meinem Code:

    // Datei Binär lesen
            Datei = fopen("D:\\test.jpg","rb");
            fseek(Datei, 0, SEEK_END );             //Dateizeiger ans Ende setzen
            size_t fileSize = ftell(Datei);         //Dateizeiger abfragen
            fseek(Datei, 0, SEEK_SET );             //Dateizeiger wieder an den Anfang setzen
    
            Memo1->Lines->Add("Größe: " + AnsiString(fileSize));
    
            Char ch[1024];
            Memo1->Lines->Add("Dateizeigerposition ----------" + AnsiString(ftell(Datei)));
    
            while((Steps=fread(ch, 1024, 1, Datei)) >0)
             {
             Memo1->Lines->Add("Dateizeigerposition ----------" + AnsiString(ftell(Datei)));
             Memo1->Lines->Add("Ausgabe ----------" + AnsiString(Steps));
    
             // Hier fehlt Code!!!
             // Variable "DateiInhalt" (AnsiString) füllen
    
             }
    
            fclose(Datei);
    
            // Datenblock wird zusammengesetzt und Länge bestimmt.
            TextSend = "-----------------------------30218195929843\r\n";
            TextSend += "Content-Disposition: form-data; name=\"userfile\"; filename=\"test.jpg\"\r\n";
            TextSend += "Content-Type: application/x-msdownload\r\n\r\n";
            TextSend += DateiInhalt + "\r\n";
            TextSend += "-----------------------------30218195929843\r\n";
            Laenge = strlen(TextSend.c_str());
    
            // Daten werden hier gesendet
            Memo1->Lines->Add("Verbindung hergestellt.");
            Socket->SendText("POST /index.php HTTP/1.1\r\n");
            Socket->SendText("Host: localhost\r\n");
            Socket->SendText("Content-Type: multipart/form-data; boundary=---------------------------30218195929843\r\n");
            Socket->SendText("Content-Length: " + AnsiString(Laenge) + "\r\n\r\n");
            Socket->SendText(TextSend);
            Memo1->Lines->Add("Verbindung beendet.");
    

    Hoffe keiner schlägt jetzt die Hände über dem Kopf zusammen, was ich da so mache. Ist aber kein produktiver Code sondern einfach nur zum Testen.

    Nu aber zu meinem Problem: Wie man dem Quellcode entnehmen kann lese ich die Daten aus der Datei (Funktioniert). Nun möchte ich den AnsiString "DateiInhalt" füllen und dann weiter unten einbinden und versenden. Wie bekomme ich die eingelesenen binären Daten in meinen AnsiString? Geht das überhaupt?

    DatenInhalt += ch;
    

    ... geht ja schon mal nicht. Die Datei wird dabei unvollständig gesendet und empfangen. Wie muss/kann ich also diese Daten übernehmen? Denke ich zu kompliziert?

    Vielen Dank für eure Hilfe.



  • Eine Datei hat in einem AnsiString nichts zusuchen. Eine Datei wird in eine Speicherbereich geladen oder per Stream verarbeitet.

    Warum nicht der Upload mit Indy und TidFTP?



  • Danke für deinen Tip. Indy hatte ich bisher einfach nicht verwendet, das wird sich aber ab JETZT ändern 😉 Mal schauen, wie es da so klappt.



  • Vielen Dank noch mal. Hat wunderbar funktioniert. Hier meine kleine Testlösung. Einige Fallstricke waren doch noch dabei - Stichwort: Content-Type
    Ich habe hier die TIdHTTP Komponente verwendet. Der Content-Type wurde von mir auf:
    multipart/form-data; boundary=---------------------------30218195929843
    gesetzt.

    Memo1->Lines->Add("Connect wird ausgeführt ...");
    
            TMemoryStream *InStream=new TMemoryStream();
            TMemoryStream *OutStream=new TMemoryStream();
    
            // Datenblock wird zusammengesetzt und Länge bestimmt.
            AnsiString TextSend;
            TextSend = "-----------------------------30218195929843\r\n";
            TextSend += "Content-Disposition: form-data; name=\"userfile\"; filename=\"bild.jpg\"\r\n";
            TextSend += "Content-Type: application/x-msdownload\r\n\r\n";
            OutStream->Write(TextSend.c_str(), strlen(TextSend.c_str()));
    
            fstream FileBin("d:\\bild.jpg", ios::in|ios::out|ios::binary);
            if (FileBin.is_open())
             {
             FileBin.seekg(0, ios::end);
             unsigned long FileSize = streamoff(FileBin.tellg());
             FileBin.seekg(0, ios::beg);
    
             char* pBuffer = new char[FileSize];
             FileBin.read(pBuffer, FileSize);
             OutStream->Write(pBuffer, FileSize);
    
             delete [] pBuffer;
             }
    
            TextSend = "\r\n-----------------------------30218195929843\r\n";
            OutStream->Write(TextSend.c_str(), strlen(TextSend.c_str()));
    
            HC->Post("http://localhost/index.php?Get=3", OutStream, InStream);
    
            InStream->Position=0;
            Memo1->Lines->LoadFromStream(InStream);
    
            delete OutStream;
            delete InStream;
    

    Ich hoffe ich konnte damit dem einen oder anderen auch noch helfen.


Anmelden zum Antworten