使用C套接字发送二进制文件中的HTTP响应 [英] Send binary file in HTTP response using C sockets

查看:211
本文介绍了使用C套接字发送二进制文件中的HTTP响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的试图在http响应发送一个二进制文件(png图片)。

I`m trying to send a binary file (png image) in http response.

FILE *file;
char *buffer;
int fileLen;

//Open file
file = fopen("1.png", "rb");
if (!file)
{
    return;
}

//Get file length
fseek(file, 0, SEEK_END);
fileLen=ftell(file);
fseek(file, 0, SEEK_SET);

//Allocate memory
buffer=(char *)malloc(fileLen+1);
if (!buffer)
{
    fprintf(stderr, "Memory error!");
    fclose(file);
    return;
}

//Read file contents into buffer
fread(buffer, fileLen, 1, file);
fclose(file);
//free(buffer);




char header[102400];

sprintf(header, 
"HTTP/1.1 200 OK\n"
"Date: Thu, 19 Feb 2009 12:27:04 GMT\n"
"Server: Apache/2.2.3\n"
"Last-Modified: Wed, 18 Jun 2003 16:05:58 GMT\n"
"ETag: \"56d-9989200-1132c580\"\n"
"Content-Type: image/png\n"
"Content-Length: %i\n"
"Accept-Ranges: bytes\n"
"Connection: close\n"
        "\n", fileLen);

char *reply = (char*)malloc(strlen(header)+fileLen);
strcpy(reply, header);
strcat(reply, buffer);

printf("msg %s\n", reply);


//return 0;
int sd = socket(PF_INET, SOCK_STREAM, 0);

struct sockaddr_in addr;
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(8081);
addr.sin_addr.s_addr = INADDR_ANY;

if(bind(sd,&addr,sizeof(addr))!=0)
{
    printf("bind error\n");
}

if (listen(sd, 16)!=0)
{
    printf("listen error\n");
}

for(;;)
{
    int size = sizeof(addr);
    int client = accept(sd, &addr, &size);

    if (client > 0)
    {
        printf("client connected\n");
        send(client, reply, strlen(reply), 0);
    }
}

但我的浏览器不明白这个=(什么我做错了什么呢?

but my browser does not understand this =( What am I doing wrong exactly?

UPD:我试图发送文本数据 - 它的确定。但是,二进制数据失败

UPD: I tried to send text data - its OK. But binary data fails

推荐答案

的问题是,你的邮件正文被视为空值终止的文本字符串(使用 strcat的的strlen 就可以了),当它不是一:它是二进制数据(PNG文件)。因此, strcat的的strlen 都停在图像(通常是比较早)在第0字节。

The problem is that your message body is being treated as a null-terminated text string (you use strcat and strlen on it), when it isn't one: it is binary data (a PNG file). Therefore, strcat and strlen both stop on the first 0 byte in the image (typically quite early).

您的程序,即使打印出响应体:注意到它提供正确的标题,但一旦PNG头(二进制数据)开始,只有几个字节

Your program is even printing out the response body: notice that it gives the correct header, but that once the PNG header (binary data) starts, there is only a few bytes.


  1. strcat的(回复,缓冲),其中缓存可能包含0字节。将其更改为的memcpy(回复+ strlen的(头),缓冲,fileLen)

  2. 发送(客户端,回复,strlen的(回复),0),其中回复可能包含0字节。 pre-计算答复的长短,或更换的strlen与的strlen(头)+ fileLen

  1. The line strcat(reply, buffer), where buffer potentially contains 0 bytes. Change it to memcpy(reply+strlen(header), buffer, fileLen).
  2. The line send(client, reply, strlen(reply), 0), where reply potentially contains 0 bytes. Pre-calculate the length of the reply, or replace the strlen with strlen(header)+fileLen.

另外一个错误是,你是不是关闭连接当你完成,所以浏览器只是等待。你需要这个,以后发送

Another bug is that you aren't closing the connection when you're done, so the browser will just wait forever. You need this, after send:

close(client);

这篇关于使用C套接字发送二进制文件中的HTTP响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆