Почему я не могу получить главную веб-страницу сервера BB C с программой Winsock2 в C? - PullRequest
0 голосов
/ 07 апреля 2020

Я написал программу, которая должна была печатать главную веб-страницу сервера BB C. Имя хоста сервера BB C - www.bbc.co.uk, а его IP-адрес - 38.160.150.31. Когда я отправляю сообщение команды HTTP GET на сервер, я не получаю главную веб-страницу BB C, вместо этого я получаю следующее:

HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Connection: close
Content-Length: 685

<HTML><HEAD>
<TITLE>Appliance Error</TITLE>
</HEAD>
<BODY>
<FONT face="Helvetica">
<big><strong></strong></big><BR>
</FONT>
<blockquote>
<TABLE border=0 cellPadding=1 width="80%">
<TR><TD>
<FONT face="Helvetica">
<big>Appliance Error (internal_error)</big>
<BR>
<BR>
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Helvetica">
An unrecoverable error was encountered: ""
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Helvetica">
This problem is unexpected. Please use the contact information below to obtain assistance.
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Helvetica" SIZE=2>
<BR>
For assistance, contact your network support team.
</FONT>
</TD></TR>
</TABLE>
</blockquote>
</FONT>
</BODY></HTML>

Мой код:

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <string.h>

int main()
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
        puts("Error: Cannot initialize winsock.");
        return 0;
    }
    SOCKET mainSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (mainSocket == INVALID_SOCKET || mainSocket == SOCKET_ERROR) {
        puts("Error: Cannot create socket.");
        return 0;
    }

    SOCKADDR_IN hostAddress;
    hostAddress.sin_family = AF_INET;
    hostAddress.sin_port = htons(80);
    hostAddress.sin_addr.S_un.S_addr = inet_addr("38.160.150.31");

    if (connect(mainSocket, (SOCKADDR*) &hostAddress, sizeof(hostAddress)) == SOCKET_ERROR) {
        printf("Cannot connect to the server. Error Code: %d\n", WSAGetLastError());
        return 0;
    }
    puts("Connected!");

    char *message = "GET HTTP/1.1\r\nHost: www.bbc.co.uk\r\n\r\n";
    int retval = send(mainSocket, message, strlen(message), 0);
    if (retval == 0) {
        puts("Error: Connection lost.");
        return 0;
    } else if (retval < 0) {
        printf("Error: Cannot send any message. Err #%d\n", WSAGetLastError());
        return 0;
    }
    char *serverReply = (char*) malloc(sizeof(char)*1000);
    if (serverReply == NULL) {
        puts("Error: Out of memory.");
        return 0;
    }
    puts("Recieved:");
    while (1) {
        retval = recv(mainSocket, serverReply, 999, 0);
        if (retval <= 0) break;
        serverReply[retval] = '\0';
        printf("%s", serverReply);
    }
    closesocket(mainSocket);
    puts("\nConnection closed.");
    WSACleanup();
    free(serverReply);
    return 1;
}

Что не так с моим кодом?

1 Ответ

2 голосов
/ 08 апреля 2020

В строке

char *message = "GET HTTP/1.1\r\nHost: www.bbc.co.uk\r\n\r\n";

цель запроса отсутствует.

3.1.1. Строка запроса

Строка запроса начинается с токена метода, за которым следует один пробел (SP), цель-запрос, еще один пробел (SP), версия протокола и заканчивается CRLF.

request-line = method SP request-target SP HTTP-version CRLF

см. https://tools.ietf.org/html/rfc7230#section -3.1.1

Поэтому строка кода должна выглядеть следующим образом:

char* message = "GET / HTTP/1.1\r\nHost: www.bbc.co.uk\r\n\r\n";

Обратите внимание на / после ПОЛУЧЕНИЯ.

Примечания стороны

nslookup www.bbc.co.uk возвращает мне другой IP-адрес. Предположительно, IP-адрес для некоторых пользователей различен, возможно, в зависимости от их географического местоположения или систем балансировки нагрузки.

Когда программа выполняется, она возвращает код состояния HTTP 301, что означает

Код ответа о состоянии перенаправленного перманентно перенаправленного протокола 301 HTTP (HyperText Transfer Protocol) указывает, что запрошенный ресурс был окончательно перемещен в URL-адрес, указанный в заголовках Location.

см. https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301

Заголовок Location:

Location: https://www.bbc.co.uk/

Обратите внимание на протокол https.

Таким образом, чтобы получить содержимое сайта BB C, вам нужно сделать запрос https. Вы, вероятно, хотите использовать библиотеку для этого, посмотрите, например, хороший ответ: { ссылка }

...