1

WinsockのTCPソケットを使用してCでMinecraftClassicServerを作成し、「ハートビート」を実行する関数を作成しています。これは、URLを返すHTTPリクエストのみで、ヘッダーやHTMLはまったく含まれていません。

データをMinecraft.netに送信します(少なくとも送信すると表示されます)が、その後数分間そこにとどまり、最終的にminecraft.netからデータを取得していないことを通知します。つまり、「HeartBeat:Recievednodata」と表示されます。 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)

応答全体を読み取れない可能性があるrecv()呼び出しを1回だけ実行しています。接続が閉じるまで(recv()が0を返すまで)読み取ることになっています。または、実際にHTTPプロトコルに従うには、応答を解析し、Content-Lengthヘッダーを探す必要があります。すべてのヘッダーを読み取り、本文のバイト数(存在する場合)を読み取ります。HTTPの細部に本当に対処するには、HTTPライブラリが必要です。

于 2012-07-05T10:34:36.297 に答える