Веб-браузер не интерпретирует изображение, переданное через массив без знака - PullRequest
0 голосов
/ 11 сентября 2011

В основном я пытаюсь захватить HTTP-запрос GET браузера через сокет и отправить этот запрос в Интернет, затем перехватить ответ и отправить его обратно в браузер.Когда перевод состоит только из текста, все работает отлично.Но при загрузке изображения.Браузер выдает ошибку «Невозможно отобразить изображение, потому что оно содержит ошибки».любая помощь будет принята с благодарностью.

#include "cc352.h"
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int
main(int argc, char **argv)
{
int                 listenfd, connfd,weblin,webcon,webwrite,n,x,y,w,w1;
socklen_t           len,wlen;
struct sockaddr_in  servaddr, cliaddr , webservad , webcliad;
unsigned char       buff[3072] , buff2[3072] ,ext[5] ,wbuff[100000];
time_t              ticks;
int                 yes = 1;
const char          *ptr;


if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
    fprintf(stderr, "socket creation failed\n");
    exit (1);
     }

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family      = AF_INET;

if (inet_pton(AF_INET,"127.0.0.1", &servaddr.sin_addr) <= 0){
    printf("inet_pton error for %s", argv[1]);
    return 1;
     }
servaddr.sin_port        = htons(4619); 

if ( (bind(listenfd, (SA *) &servaddr, sizeof(servaddr))) < 0) {
    fprintf(stderr, "bind failed\n");
    exit (1);
    fprintf(stdout, "bindd completed\n");
     }


if ( (weblin = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
    fprintf(stderr, "socket creation failed\n");
    exit (1);
     }
printf("weblin socket created \n");

bzero(&webservad, sizeof(webservad));
webservad.sin_family      = AF_INET;
webservad.sin_port        = htons(80); 

if (inet_pton(AF_INET,"208.80.152.211", &webservad.sin_addr) <= 0){
    printf("inet_pton error for %s", argv[1]);
    return 1;
     }


if (connect(weblin, (SA *) &webservad, sizeof(webservad)) < 0) {
    printf("weblin connect error");
    return 1; 
     }
printf("weblin connected \n");


if ( listen(listenfd, LISTENQ) < 0) {
    fprintf(stderr, "listen failed\n");
    exit (1);
    fprintf(stderr, "listning\n");
     }


    len = sizeof(cliaddr);
    if ( (connfd = accept(listenfd, (SA *) &cliaddr, &len)) < 0 ) {
    fprintf(stderr, "accept failed\n");
    exit (1);
     }
fprintf(stdout, "Connection accepted\n");


        int d=0;

           read(connfd,&buff, 3071); // Reads GET request from browser save it to array buff
           unsigned char bron[strlen(buff)];

           for(d=0 ; d<=sizeof(bron) ; d++){
           bron[d]=buff[d];
           }
           write(weblin,bron, sizeof(bron)); // Send the data to Internet
           printf("%s \n",bron);


           while(d=read(weblin,&wbuff, 100000)>0){ //Reads the reply from Internet and save it to wbuff
           unsigned char wron[strlen(wbuff)];

           for(d=0 ; d<=sizeof(wron) ; d++ ){
            wron[d]=wbuff[d];
            }
           write(connfd,wbuff,strlen(wbuff)); //Writes the reply to the browser
           printf("%s \n",wron);
    }


 close(connfd);
 close(listenfd);
 close(weblin);
}

Ответы [ 2 ]

5 голосов
/ 11 сентября 2011

strlen предназначено для строк C, которые 0 завершены. 0 совершенно верно в середине двоичного файла изображения. Так что вы, вероятно, не отправляете столько данных, сколько получили. (Или даже больше данных, чем вы получили, возможно, даже больше, чем то, что ваш буфер должен содержать, если изображение не содержит 0.)

Никогда ничего не делайте с буфером, который вы передали read, если не проверяете, что вызов read был успешным. Вам нужно , чтобы использовать возвращаемое значение read, потому что это единственное, что говорит вам, сколько данных вы получили.

Вы предполагаете, что прочитаете весь запрос за один read звонок. Ничто не гарантирует этого.

(я не понимаю, что вы пытаетесь сделать с wron, и bron в ненужном в вашем коде. И есть функция memcpy. Используйте ее, а не катите свою собственную.)

(И вы должны проверять код возврата всех ваших write вызовов.)

0 голосов
/ 11 сентября 2011

Я не просмотрел ваш код целиком. Но (одна из) проблема, безусловно, заключается в том, что вы рассматриваете буферы как строковые буферы (то есть NULL завершенные буферы). Особенно использование strlen() для определения размера буферов.

Например, эта строка (в конце вашего кода):

write(connfd,wbuff,strlen(wbuff))

Это не удастся для любой полезной нагрузки, которая не содержит текстовых данных, как в случае с изображениями.

...