views:

531

answers:

2

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.

+4  A: 

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.

+4  A: 

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) http://stackoverflow.com/questions/873615/giving-c-application-a-http-web-server-functionality

The Unknown
Thanks for the suggestion, I'm checking it out right now (even though I was just fooling around, this looks interesting!)
kitchen
+1 for Mongoose. See my original question referred to by the post The Unknown pointed you to: http://stackoverflow.com/questions/175507/c-c-web-server-library
Bklyn