Web 浏览器不解释通过无符号字符数组传递的图像

发布于 2024-12-04 04:48:37 字数 2923 浏览 0 评论 0原文

我想做的基本上是通过套接字捕获浏览器的 HTTP GET 请求并将该请求发送到 Internet,然后捕获回复并将其发送回浏览器。当传输仅包含文本时,一切都很完美。但是当下载图像时。浏览器给出错误“无法显示图像,因为它包含错误”。任何帮助将不胜感激。

#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);
}

What I am trying to do basically is to capture the HTTP GET request of the browser via a socket and send that request to the Internet, then capture the reply and send it back to the browser. When the transfer consist only of text, every thing works perfectly. But when downloading an image. browser gives the error "cant display the image because it contains errors". any help would be greatly appreciated.

#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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

硬不硬你别怂 2024-12-11 04:48:37

strlen 适用于以 0 结尾的 C 字符串。 0 在二进制图像文件的中间是完全有效的。因此,您可能没有发送尽可能多的数据。 (或者甚至比您获得的数据更多,甚至可能超出缓冲区应容纳的数据,如果图像恰好包含0.)

如果您不检查 read 调用是否成功,切勿对传递给 read 的缓冲区执行任何操作。您需要使用read的返回值,因为这是唯一告诉您获得了多少数据的东西。

您假设您将在一次 read 调用中读取整个请求。没有什么能保证这一点。

(我不明白你想用代码中不必要的 wronbron 做什么。还有一个 memcpy 函数。使用它而不是自己编写。)

(并且您应该检查所有 write 调用的返回代码。)

strlen is meant for C strings, that are 0 terminated. 0 is perfectly valid in the middle of a binary image file. So you're probably not sending as much data as you got. (Or even more data than you got, possibly even more than what your buffer is supposed to hold, if the image happens not to contain a 0.)

Never do anything with the buffer you've passed to read if you don't check that the read call was successful. You need to use read's return value because that's the only thing that tells you how much data you got.

You're assuming that you'll read the whole request in a single read call. Nothing guarantees that.

(I don't understand what you're trying to do with wron, and bron in un-necessary in your code. And there's a memcpy function. Use it rather than rolling your own.)

(And you should be checking the return code of all your write calls.)

没企图 2024-12-11 04:48:37

我没有完整地浏览你的代码。但是(其中一个)问题肯定是您将缓冲区视为字符串缓冲区(即 NULL 终止的缓冲区)。特别是使用 strlen() 来查找缓冲区的大小。

例如这一行(在代码末尾):

write(connfd,wbuff,strlen(wbuff))

对于任何不包含纯文本数据的有效负载(如图像的情况),这都会失败。

I didn't go through your code in it's entirety. But (one of) the problem is surely with your treatment of buffers as string buffers(That is NULL terminated buffers). Specially the usage of strlen() to find size of buffers.

For example this line (at the end of your code):

write(connfd,wbuff,strlen(wbuff))

This will fail for any payload, which does not contain plain-text data, as is the case with images.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文