基本C ++套接字编程中的异常HTTP响应

时间:2009-10-19 04:47:14

标签: c++ c http sockets

我已经在C ++中设置了一个基本的HTTP客户端,到目前为止工作正常。这是一个学校作业,所以还有很多工作要做,但我遇到了问题。

我在while循环中使用recv()函数,将响应的各个部分重复添加到我的响应缓冲区,然后每次输出该缓冲区。问题是,在每个响应结束时,HTTP请求也会得到加强。

例如,响应将是页面源代码的一部分,然后是“GET / HTTP / 1.1 ...”,然后是下一个块,然后是“GET ...”,所以上。

这是我的相关代码:

 // Prepare request
char request[] = "HEAD /index.html HTTP/1.1\r\nHOST: www.google.com\r\nCONNECTION: close\r\n\r\n";

// Send request
len = send(sockfd, request, sizeof(request), 0);

// Write/output response
while (recv(sockfd, buf, sizeof(buf), 0) != 0)
{
    // Read & output response
    printf("%s", buf);
}

4 个答案:

答案 0 :(得分:7)

缓冲区不是以null结尾,这是C ++中字符串所必需的。当你看到“额外的GET”时,你会看到你不应该的内存,因为stdlib试图打印你的缓冲区,但从未找到'\0'个字符。

快速解决方法是强制终止缓冲区:

int n = 1;
while (n > 0) {
    n = recv(sockfd, buf, sizeof(buf), 0);
    if (n > 0) {
        // null terminate the buffer so that we can print it
        buf[n] = '\0';

        // output response
        printf("%s", buf);
    }
}

答案 1 :(得分:1)

我怀疑是因为您的buf分配在request下方的内存中。当您在缓冲区上调用printf时,printf会在找到NUL字符(标记字符串结尾)之前尽可能多地打印。如果没有,它将直接进入请求。通常,不会有一个,因为recv用于接收二进制数据,并且不知道您想要将其输出视为字符串。

一个快速解决方法是将接收操作限制为sizeof(buf)-1,并使用返回数据的大小自行显式添加NUL终止符:

while ((nr = recv(sockfd, buf, sizeof(buf), 0)) > 0)
{
    buf[nr] = 0;
    ...
}

当然,为了(稍微)安全,您需要确保始终可以获得可打印的数据。

答案 2 :(得分:0)

recv没有向收到的缓冲区添加\0字符串终止符 - 它只适用于原始二进制文件。因此,printf正在运行buf缓冲区的发送(显然最终会查看您的request缓冲区。)

buf的末尾添加一个nul-terminator,或者使用putchar()一次打印一个字符缓冲区(这两种方法都需要存储{返回的值} {1}})。

答案 3 :(得分:0)

recv调用不会为null-terminate buf;相反,它只会为您提供从电线接收的原始数据。您需要保存recv的返回值,然后在打印之前将自己的空终止字节添加到buf中。因此,您只能要求sizeof(buf)-1个字节。