我正在尝试使用memcpy()函数将从read()获得的一些二进制数据存储到我的缓冲区中。
基本上,我想在我的缓冲区中存储buf:
#define MAX_BUFFER_SIZE 256
//...
char *
httpget(const char * domain, const int port, const char * headers)
{
int sockfd;
int buf_size = MAX_BUFFER_SIZE;
struct sockaddr_in sock_addr;
struct hostent * host;
char * buffer;
char * newbuf;
char * tbuf;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if( sockfd == -1 )
{
return NULL;
}
host = gethostbyname(domain);
if( NULL == host )
{
close(sockfd);
return NULL;
}
memset(&sock_addr, '\0', sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
memcpy( &sock_addr.sin_addr.s_addr,
host -> h_addr,
host -> h_length );
sock_addr.sin_port = htons(port);
if( connect(sockfd, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) == -1)
{
close(sockfd);
return NULL;
}
if( write(sockfd, headers, strlen(headers) + 1) == -1)
{
close(sockfd);
return NULL;
}
buffer = malloc( MAX_BUFFER_SIZE );
tbuf = malloc( MAX_BUFFER_SIZE );
if(buffer == NULL || tbuf == NULL)
{
return NULL;
}
int bytesloaded = 0;
int readed;
while( (readed = read(sockfd, tbuf, MAX_BUFFER_SIZE)) > 0 )
{
if(bytesloaded + readed >= buf_size)
{
buf_size = buf_size + MAX_BUFFER_SIZE;
newbuf = realloc(buffer, buf_size);
if(newbuf != NULL)
{
buffer = newbuf;
}
else
{
return NULL;
}
}
memcpy(buffer, tbuf, readed);
bytesloaded += readed;
}
close(sockfd);
printf("buffer = %s", buffer);
return buffer;
}
但是当我printf(“%s”,缓冲区)时;我只获得了具有7007内容长度的二进制的HTTP标头和�PNG
字符。怎么解决这个问题?我希望这对你来说很清楚。任何帮助都非常感谢。谢谢。
答案 0 :(得分:3)
我想你想要:
memcpy(buffer + bytesloaded, buf, readed);
当您尝试使用printf("%s",buffer)
转储时,您没有看到整个响应,因为响应中发送的.png
图像是可能包含空'\0'
的二进制数据字节,printf()
将在此时停止。
您有各种其他选项来检查响应中返回的数据(或有关它的信息):查看调试器中的buffer
,转储bytesloaded
变量,转储{{1}使用一个函数将其转换为十六进制显示,和/或将响应体(在标题和标题后面的CR / LF之后)写入buffer
文件并在某事物中查看它这将显示图像。
答案 1 :(得分:1)
memcpy中有一个拼写错误,指的是buffe而不是缓冲区,虽然它可能只出现在帖子而不是你的实际代码中(我不相信它会用它编译)如果它是那肯定是问题所在。
更新:虽然其他答案表明可能存在空字节,但是在png头规范中没有位置,空字节应该是标题的一部分,所以唯一的位置可能是正文,但是因为你没有数据然后唯一的选择可能是,如果它是身体中的第一件事我认为真的是一个后壳,所以你可能尝试使用不同的信息来源,如另一个图像或其他网址,如果问题坚持所有的png图像然后它是printf和标题之间的东西(因此如果它在标题中有一个空字节,那么无论如何它都值得入侵)。
但请注意,在字母PNG出现CRLF然后出现EOF之后,虽然如果printf会出现问题会很有趣,但如果这是问题,那么转储到文件也不一定是解决方案除非你用png查看器打开它。
实际上你没有包含你的套接字源代码,因此如果是你自己编写的代码,请确保它不会在第一个EOF上停止,因为它是png头的一部分。
答案 2 :(得分:1)
由于printf(3)
格式化指令%s
将字节作为字符打印,直到遇到ASCII NUL
字符。 PNG format可能允许NUL
或者第9个字节 - 前8个字节是0x89
,PNG
,然后是一些空白字符到发现特定种类的白色空间修剪。
我建议使用不同的printf(3)
格式说明符来查看相关数据 - 或将其写入调试文件,以便您可以使用常用的十六进制编辑器对其进行编辑以验证其内容。