我正在开发一个需要解析Chunked类型HTTP传输的客户端。我试着用下面的方法弄清楚错误,并且如果有人能够更快地捕捉到我的错误,我会很感激。总结一下这个问题:似乎客户端没有收到所有的块,从而搞砸了剩下的进程。提前谢谢!
while(cflag){
pfile_chunk = malloc(CHUNK_SIZE+1);
memset(pfile_chunk, 0, CHUNK_SIZE);
cPtr = pfile_chunk;
cPtr2 = NULL;
k=0;
while(*(cPtr-1) != '\n'){
k++;
recv(sock, cPtr, 1, 0);
cPtr = pfile_chunk+k;
}
cPtr2 = strchr(pfile_chunk, '\r');
*cPtr2 = '\0';
sscanf(pfile_chunk, "%x", &l);
if(l == 0)
break;
printf("\nServer wants to deliver %ld bytes.\n", l);
pfile_chunk = realloc(pfile_chunk, l+1);
memset(pfile_chunk, 0, l);
recv(sock, pfile_chunk, l, 0);
fputs(pfile_chunk, f);
printf("GOT THIS, SIZE %ld:\n%s\n", strlen(pfile_chunk), pfile_chunk);
//get next \r\n bytes.
recv(sock, NULL, 2, 0);
}
答案 0 :(得分:5)
至少,你应该检查recv
的返回值,看看你是否得到了你期望获得的字节数。
网络上肯定可以进行短读,因为系统调用将在您拨打电话时返回套接字接收缓冲区中可用的内容。
实现循环,直到读入整个块,或将MSG_WAITALL
标志传递给最后一个参数中的recv
。但是,您仍需要检查来自recv
的错误。
ssize_t r = recv(sock, pfile_chunk, l, MSG_WAITALL);
if (r < l) {
/* check for errors ... */
} else {
/* got the data */
}
答案 1 :(得分:2)
看起来你的while
循环中的检查的第一个取消引用将在数组开始之前访问,这可能不是所希望的行为。希望该内存位置通常不包含\n
。这可能会弄乱你的read
。我希望它可能包含一些与malloc
有关的信息,这些信息不太可能是\n
,因此您可能永远不会发现问题。
此外,希望您可以相信套接字的另一端在发送CHUNK_SIZE+1
之前不要发送超过\n
的内容。否则,它可能会出错。但是,通常情况下,我希望发送者只发送10个或更少的ASCII数字字符和一个块头的CRLF,但理论上他们可以发送一堆长的块扩展头字段。
除此之外,user315052已经找到了一个更重要的问题,你应该告诉recv方法等待你请求的所有数据,或者检查它实际读取了多少数据。