Web 浏览器不解释通过无符号字符数组传递的图像
我想做的基本上是通过套接字捕获浏览器的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
strlen
适用于以0
结尾的 C 字符串。0
在二进制图像文件的中间是完全有效的。因此,您可能没有发送尽可能多的数据。 (或者甚至比您获得的数据更多,甚至可能超出缓冲区应容纳的数据,如果图像恰好不包含0
.)如果您不检查
read
调用是否成功,切勿对传递给read
的缓冲区执行任何操作。您需要使用read
的返回值,因为这是唯一告诉您获得了多少数据的东西。您假设您将在一次
read
调用中读取整个请求。没有什么能保证这一点。(我不明白你想用代码中不必要的
wron
和bron
做什么。还有一个memcpy
函数。使用它而不是自己编写。)(并且您应该检查所有
write
调用的返回代码。)strlen
is meant for C strings, that are0
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 a0
.)Never do anything with the buffer you've passed to
read
if you don't check that theread
call was successful. You need to useread
'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
, andbron
in un-necessary in your code. And there's amemcpy
function. Use it rather than rolling your own.)(And you should be checking the return code of all your
write
calls.)我没有完整地浏览你的代码。但是(其中一个)问题肯定是您将缓冲区视为字符串缓冲区(即
NULL
终止的缓冲区)。特别是使用strlen()
来查找缓冲区的大小。例如这一行(在代码末尾):
对于任何不包含纯文本数据的有效负载(如图像的情况),这都会失败。
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 ofstrlen()
to find size of buffers.For example this line (at the end of your code):
This will fail for any payload, which does not contain plain-text data, as is the case with images.