C++ — простой сервер, который отправляет клиентам простой HTML.

StackOverflow https://stackoverflow.com/questions/873978

  •  22-08-2019
  •  | 
  •  

Вопрос

Теперь я просто дурачусь с этим и не понимаю, почему это не работает.

#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <cassert>

const char html[] = "HTTP/1.1 200 OK\r\n"
"Connection: close\r\n"
"Content-type: text/html\r\n"
"\r\n"
"<html>\r\n"
"<head>\r\n"
"<title>Hello, world!</title>\r\n"
"</head>\r\n"
"<body>\r\n"
"<h1>Hello, world!</h1>\r\n"
"</body>\r\n"
"</html>\r\n\r\n";

int main() {
    WSADATA wsa;

    assert( WSAStartup( MAKEWORD( 2, 2 ), &wsa ) == 0 );

    addrinfo *res = NULL;
    addrinfo hints;

    ZeroMemory( &hints, sizeof( hints ) );

    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;

    assert( getaddrinfo( NULL, "80", &hints, &res ) == 0 );

    SOCKET s = socket( res->ai_family, res->ai_socktype, res->ai_protocol );

    assert( s != INVALID_SOCKET );
    assert( bind( s, res->ai_addr, (int)res->ai_addrlen ) != SOCKET_ERROR );
    assert( listen( s, SOMAXCONN ) != SOCKET_ERROR );

    SOCKET client = accept( s, NULL, NULL );

    assert( client != INVALID_SOCKET );

    char buffer[512];
    int bytes;

    bytes = recv( client, buffer, 512, 0 );

    for ( int i = 0; i < bytes; ++i ) {
        std::cout << buffer[i];
    }

    assert( send( client, html, strlen( html ) - 1, 0 ) > 0 );
    assert( shutdown( client, SD_BOTH ) != SOCKET_ERROR );

    closesocket( client );
    WSACleanup();

    return 0;
}

Когда я компилирую и запускаю это, а затем перехожу к 127.0.0.1 в своем браузере, я получаю это в своей консоли:

ПОЛУЧИТЬ / HTTP/1.1

Хозяин:127.0.0.1

Связь:поддерживать жизнь

Пользователь-Агент:Мозилла/5.0 (Windows;У;Windows НТ 5.1;en-US) AppleWebKit/530.5 (K HTML, например Gecko) Chrome/2.0.172.8 Safari/530.5

Управление кэшем:максимальный возраст=0

Принимать:application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,/;q=0,5

Принять-кодирование:gzip, выкачивание, bzip2, sdch

Принять-Язык:ru-US,en;q=0,8

Принять-кодировка:ISO-8859-1,utf-8;q=0,7,*;q=0,3

РЕДАКТИРОВАТЬ - Я обновил отправляемый HTML-код.Я только что протестировал это с Mozilla Firefox и Google Chrome, и это работает в Firefox, но не в Chrome!

РЕДАКТИРОВАТЬ 2 - Похоже, что причина, по которой он работал в Firefox, но не в Chrome, заключалась в том, что Firefox отображает HTML в том виде, в котором он был получен, в то время как Chrome ждет закрытия соединения, прежде чем выполнять какой-либо рендеринг.Я добавил код для закрытия сокета, и он сработал.Я обновил свой код, указав рабочий источник.

Это было полезно?

Решение

Вам нужно отправить обратно строку состояния:

HTTP/1.1 200 ОК

перед заголовками ответов.

См. Fiddler (www.fiddler2.com), чтобы лучше понять, как выглядят правильные HTTP-ответы.

Что касается вашего последующего редактирования, все браузеры ждут определенного объема данных, прежде чем начать рендеринг;Ограничение Chrome отличается от ограничения Firefox.Если бы вы установили Content-Length или использовали кодировку HTTP Chunked, вы бы увидели правильное поведение.

Другие советы

Посмотрите на Мангуста http://code.google.com/p/mongoose/Это автономная библиотека, которая представляет собой многопоточный веб-сервер http и имеет очень простой API (но полный).Через несколько минут мне удалось привязать его к уже существующему приложению.

Сегодня у меня был тот же вопрос (чтобы предоставить моему приложению на C++ веб-конец) Предоставление приложению C++ функциональности веб-сервера HTTP

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top