简体   繁体   English

Winsock recv()未接收到任何数据(C)

[英]Winsock recv() not receiving any data (C)

I'm writing a Minecraft Classic Server in C using TCP sockets in Winsock and I'm writing the function to perform a 'heartbeat', just an HTTP request which should return a URL to me - no headers or HTML at all. 我正在用Winsock中的TCP套接字在C中编写一个Minecraft Classic Server,并且正在编写执行“心跳”功能,只是一个HTTP请求,该请求应该向我返回一个URL-根本没有标题或HTML。

It sends the data to Minecraft.net (at least it says it does) but it just sits there for a few minutes after that and eventually tells me that it got no data from minecraft.net, ie it reads "HeartBeat: Recieved no data from minecraft.net" 它会将数据发送到Minecraft.net(至少它说是这样),但是在那之后只停留了几分钟,最终告诉我,它没有来自minecraft.net的数据,即它显示为“ HeartBeat:未接收任何数据”。来自minecraft.net”

I have the following code so far (excluding WSAStartup etc.): 到目前为止,我有以下代码(不包括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;
    }
}

Could someone please point out where I've gone wrong? 有人可以指出我哪里出问题了吗? Thanks a million. 太感谢了。

You're not sending an HTTP request. 您没有发送HTTP请求。

A (minimal) HTTP request would have to be at least the string: (最小)HTTP请求必须至少为字符串:

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

Or in the case of HTTP 0.9: 或使用HTTP 0.9:

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

You must send just that string, not the whole request buffer containing a lot of 0 bytes, so do: 您必须仅发送该字符串,而不是发送包含很多0字节的整个请求缓冲区,因此请执行以下操作:

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

You are doing just 1 recv() call, that might not read the entire response. 您只执行1个recv()调用,但可能无法读取整个响应。 You're supposed to read until the connection closes (until recv() returns 0). 您应该阅读直到连接关闭(直到recv()返回0)为止。 Or to really follow the HTTP protocol, you need to parse the response, look for a Content-Length header. 或者,要真正遵循HTTP协议,您需要解析响应,查找Content-Length标头。 Read all the headers, then read the number of bytes in the body (if any). 读取所有标头,然后读取正文中的字节数(如果有)。 To really cope with all the minute details of HTTP, you really need a HTTP library though. 为了真正应对HTTP的所有细节,您实际上确实需要一个HTTP库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM