Einlesen eines Bildes in ein char*



  • Hallo,

    bin gerade dabei einen kleinen Webserver zu schreiben der ganz einfache HTML-Seiten mit Bildern anzeigen kann. (Praktikumsaufgabe für die Uni)

    Ich werte nun die entsprechende Anfrage aus, lese die gewünschte Datei ein und sende die Daten über dan entsprechenden Socket an den Client zurück.

    Funktioniert auch ganz gut bis auf Bilder, die zeigt er irgendwie nicht an.
    Habe in diversen Foren und google noch nichts dazu gefunden.

    Vielen Dank schon mal für Hilfe,
    Matthias

    Relevant ist der Code in der While-Schleifen, der Rest ist nur als Info zum Verständnis.

    // Senden der Angeforderten Daten wenn vorhanden, sonst einen Fehlerstring.
        char *request = new char[BUF_SIZ];
        const char* sFileName;
        FILE *fiDatei;
        int iChar;
        int i = 0;
    
        sFileName = getStrBetweenBlanks("GET ", buffer, '/');
        printf("\nFilename: %s\n", sFileName);
    
        fiDatei = fopen(sFileName, "rb");
        if(fiDatei != NULL)
        {
            while( (iChar=fgetc(fiDatei)) != EOF)
            {
                request[i] = (char) iChar;
                i++;
                if (i >= BUF_SIZ)
                {
                    i = 0;
                    if (send(sock, request, strlen(request), 0) == -1)
                        perror("send() failed");
    
                    request = new char[BUF_SIZ];
                }
            }
            // Senden vom Rest der Datei
            printf("%s", request);
            if (send(sock, request, strlen(request), 0) == -1)
                perror("send() failed");
        }
        else
            { printf("Konnte Datei nicht finden bzw. oeffnen!\n");
              return 0;}
    
        fclose(fiDatei);
        return 0;
    


  • Mal abgesehen davon, dass der Code ein übler Mischmach aus C und C++ ist (C/C++ eben 😋 ):

    strlen(request)
    

    funktioniert für Texte, bei Bildern ist ein Wert einer Farbkomponente eines Pixels von 0 ein durchaus häufig anzutreffender Wert und sollte nicht als Ende der Daten angesehen werden. Du musst dir eben selber merken, wieviel eingelesen wurde (innerhalb der Schleife klar, für die restlichen Daten ist eine zusätzliche Buchführung nötig).

    // innerhalb der while-Schleife
    request = new char[BUF_SIZ];
    

    Die Frage ist nun, ob send(..) bei dir blockiert, wenn ja, ist dieser Aufruf überflüssig,. In beiden Fällen hast du bereits im Vorfeld Speicher angefordert, den du so nicht wieder freigeben kannst.

    Obgligatorisch: Außerdem fehlt

    delete [] request;
    

    was natürlich auch keinen Sinn macht (s.o.).

    Du könntest einen std::vector<char> request nehmen, ihn mittels reserve dazu bringen, genug Speicher anzufordern, innerhalb der Schleife mit push_back Daten anhängen und nach dem Senden (falls blockierend) clear aufzurufen (der reservierte Speicherplatz bleibt weiterhin bestehen, lediglich der interne Index wird auf 0 gesetzt, sodass im nächsten Durchlauf wieder mit push_back gearbeitet werden kann).



  • [cpp]while( (iChar=fgetc(fiDatei)) != EOF)
            {
                request[i] = (char) iChar; 
    [/cpp]
    

    du kannst aus einem char keinen string zaubern und außerdem liest strlen nur bis zur ersten 0. in einam bild können aber nullen mit anschließenden daten enthalten sein, diese würden nicht übertragen werden.



  • Hi,

    strlen(request)
    

    funktioniert für Texte, bei Bildern ist ein Wert einer Farbkomponente eines Pixels von 0 ein durchaus häufig anzutreffender Wert und sollte nicht als Ende der Daten angesehen werden. Du musst dir eben selber merken, wieviel eingelesen wurde (innerhalb der Schleife klar, für die restlichen Daten ist eine zusätzliche Buchführung nötig).

    das ist mein Fehler gewesen, jetzt werden auch Bilder auf der Webseite angezeigt.

    Vielen Dank an Hmmh und wtf++,



  • Aber, wie schon geschrieben, solltest du noch einmal die Speicherverwaltung überarbeiten...(und entweder die Stärken von C++ nutzen [vector!!!] oder konsequent in C arbeiten [was aber anscheindend nicht notwendig ist]).


Log in to reply