Home > Back-end >  Why does this minimal HTTP test server fail half of the time?
Why does this minimal HTTP test server fail half of the time?

Time:06-28

I'm trying to write a minimal HTTP server on Windows and see the response in Chrome with enter image description here

#include <winsock2.h>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
int main()
{
    WSADATA WSAData;
    SOCKET sock, csock;
    SOCKADDR_IN sin, csin;
    WSAStartup(MAKEWORD(2,0), &WSAData);
    sock = socket(AF_INET, SOCK_STREAM, 0);
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(5000);
    bind(sock, (SOCKADDR *) &sin, sizeof(sin));
    listen(sock, 0);
    while(1)
    {
        int sinsize = sizeof(csin);
        if((csock = accept(sock, (SOCKADDR *) &csin, &sinsize)) != INVALID_SOCKET)
        {
            std::string response = "HTTP/1.1 200 OK\nConnection: close\nContent-Length: 11\n\nHello World";
            send(csock, response.c_str(), response.size(), 0);
            std::cout << "done";
            closesocket(csock);
        }
    }
    return 0;
}

CodePudding user response:

You fail to read the client's request before closing the connection. This usually results in the server sending a RST back to the client, which can cause the ERR_CONNECTION_ABORTED when it is processed before the response itself was processed.

As observed by another (deleted) answer, this can be "mitigated" by adding some short delay before the connection is closed, so that the response is processed by the client.

The right fix is to read the request from the client, though.

Apart from that, your response is not valid HTTP since you use \n instead of \r\n as line end and header end.


Working solution:

#include <winsock2.h>
#include <iostream>
#define DEFAULT_BUFLEN 8192
#pragma comment(lib, "ws2_32.lib")
int main()
{
    char recvbuf[DEFAULT_BUFLEN];
    WSADATA WSAData;
    SOCKET sock, csock;
    SOCKADDR_IN sin, csin;
    WSAStartup(MAKEWORD(2,0), &WSAData);
    sock = socket(AF_INET, SOCK_STREAM, 0);
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(5000);
    bind(sock, (SOCKADDR *) &sin, sizeof(sin));
    listen(sock, 0);
    while (1) 
    {
        int sinsize = sizeof(csin);
        if ((csock = accept(sock, (SOCKADDR *) &csin, &sinsize)) != INVALID_SOCKET)
        {
            recv(csock, recvbuf, DEFAULT_BUFLEN, 0);
            std::string response = "HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Length: 11\r\n\r\nHello World";
            send(csock, response.c_str(), response.size(), 0);
            std::cout << "done";
            closesocket(csock);
        }
    }
    return 0;
}
  • Related