1

我正在使用 Winsock 中的 TCP 套接字在 C 中编写一个 Minecraft Classic Server,我正在编写执行“心跳”的函数,只是一个 HTTP 请求,它应该向我返回一个 URL - 根本没有标题或 HTML。

它将数据发送到 Minecraft.net(至少它是这么说的),但在那之后它只是在那里呆了几分钟,最终告诉我它没有从 minecraft.net 获得数据,即它显示“HeartBeat: Recieved no data来自 minecraft.net"

到目前为止,我有以下代码(不包括 WSAStartup 等):

void HeartBeat()
{
    unsigned int clSock;
    struct hostent *host;
    struct sockaddr_in server_addr;
    char buffer[128] = "";
    char request[256] = "GET /"; //(I will not show the rest of the request...)
    if((clSock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
            printf("HeartBeat: Error creating socket\n");
            return;
    } else {
            printf("HeartBeat: Success in creating socket\n");
    }
    printf("HeartBeat: Resolving hostname 'www.minecraft.net'... ");
    if((host = gethostbyname("www.minecraft.net")) == NULL)
    {
        printf("failed\n");
        return;
    } else {
        printf("success!\n");
    }
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(80);
    server_addr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
    if (connect(clSock, (SOCKADDR*) &server_addr, sizeof(server_addr)) == SOCKET_ERROR)
    {
        printf("HeartBeat: Error conneting to www.minecraft.net\n");
        return;
    } else {
        printf("HeartBeat: Connected to www.minecraft.net\n");
    }
    if (send(clSock, request, sizeof(request), 0) < 0)
    {
        printf("HeartBeat: Sending data failed.\n");
        closesocket(clSock);
        return;
    } else {
        printf("HeartBeat: Success in sending data.\n");
    }
    if ((recv(clSock, buffer, sizeof(buffer), 0)) == 0)
    {
        printf("HeartBeat: Received no data from www.minecraft.net\n");
        closesocket(clSock);
        return;
    } else {
        printf("HeartBeat: Yay, success! Url is '%s'", buffer);
        closesocket(clSock);
        return;
    }
}

有人可以指出我哪里出错了吗?太感谢了。

4

1 回答 1

1

您没有发送 HTTP 请求。

(最小)HTTP 请求必须至少是字符串:

char request[256] ="GET / HTTP/1.0\r\n\r\n";

或者在 HTTP 0.9 的情况下:

char request[256] ="GET /\r\n\r\n";

您必须只发送该字符串,而不是包含大量 0 字节的整个请求缓冲区,因此请执行以下操作:

 send(clSock, request, strlen(request), 0)

您只进行了 1 个 recv() 调用,这可能不会读取整个响应。您应该阅读直到连接关闭(直到 recv() 返回 0)。或者要真正遵循 HTTP 协议,您需要解析响应,查找 Content-Length 标头。读取所有标题,然后读取正文中的字节数(如果有)。但是,要真正处理 HTTP 的所有细节,您确实需要一个 HTTP 库。

于 2012-07-05T10:34:36.297 回答