Question

Now, I'm just fooling around with this and I'm not sure as to why this isn't working.

#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;
}

When I compile and run this and then navigate to 127.0.0.1 in my browser I get this in my console:

GET / HTTP/1.1

Host: 127.0.0.1

Connection: keep-alive

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/530.5 (K HTML, like Gecko) Chrome/2.0.172.8 Safari/530.5

Cache-Control: max-age=0

Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,/;q=0.5

Accept-Encoding: gzip,deflate,bzip2,sdch

Accept-Language: en-US,en;q=0.8

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

EDIT - I've updated the HTML I'm sending. I just tested this with Mozilla Firefox and Google Chrome and it works in Firefox, but not Chrome!

EDIT 2 - So it seems that the reason it was working on Firefox, but not Chrome, was because Firefox displays the HTML as its received, while Chrome waits for the connection to close before doing any rendering. I added the code to close the socket and it worked. I've updated my code with the working source.

Was it helpful?

Solution

You need to send back the status line:

HTTP/1.1 200 OK

preceding your response headers.

See Fiddler (www.fiddler2.com) to get a better idea of what proper HTTP responses look like.

Regarding your later edit, all browsers wait for a certain amount of data before starting rendering; Chrome's limit is different than Firefox's. If you had set a Content-Length or used HTTP Chunked encoding, you would have seen proper behavior.

OTHER TIPS

Look at Mongoose http://code.google.com/p/mongoose/ It's a self contained library that's a multithreaded http web server and has a super simple api (yet complete). Within a few minutes I was able to bind it to my already existing app.

I had the same question earlier today (to give my C++ application a web end) Giving C++ Application a HTTP Web Server Functionality

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top