4

我正在开发一个需要解析 Chunked-type 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);
}
4

2 回答 2

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 */
}
于 2012-07-23T22:27:09.077 回答
2

看起来您对while循环中的检查的第一次取消引用将在数组开始之前访问,这可能不是所需的行为。希望该内存位置通常不包含\n. 那可能会搞砸你的read. 我希望它可能包含一些与您有关的信息malloc,这不太可能是\n,因此您可能永远不会从中看到问题。

另外,希望您可以相信套接字的另一端不会比CHUNK_SIZE+1他们给您的\n. 否则,它可能会出现段故障。不过,通常情况下,我希望发送者只发送 10 个或更少的 ASCII 数字字符和一个块头的 CRLF,但理论上他们可以发送一堆长的块扩展头字段。

除此之外,user315052 已经发现了一个更重要的问题,您应该告诉 recv 方法等待您请求的所有数据,或者检查它实际读取了多少数据。

于 2012-10-11T18:46:50.580 回答