Search code examples
csocketshttpserver

Creating server with C sockets and getting error


I'm following a tutorial for creating an HTTP server with sockets using C. I'm on Windows using the gcc compiler. The server runs and I can even hit it and get data back when using a custom client built from C sockets. But When I try run the command

"curl -o - http://127.0.0.1:8001"

to connect to my server, I receive the error:

curl : Unable to read data from the transport connection: An existing connection was forcibly closed by the remote
host.

My server output shows the connection is trying to be made, but doesn't show any errors. Here is my code.. http_server.c

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

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>

int main()
{
    //open a file to server
    FILE *html_data;
    html_data = fopen("index.html", "r");
    
    
    
    char response_data[1024];
    fgets(response_data, 1024, html_data);
    
    char http_header[2048] = "HTTP/1.1 200 OK\r\n\r\n";
    strcat(http_header, response_data);
    
    
    
    //create a socket
    int server_socket;
    server_socket = socket(AF_INET, SOCK_STREAM,0);
    
    // specify an address for the socket
    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(8001);
    server_address.sin_addr.s_addr = INADDR_ANY;
    
    //bind the socket to our specified IP and port
    bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address));

    listen(server_socket,5);

    int client_socket;
    

    
while(1) {

    client_socket = accept(server_socket, NULL, NULL);
    
    printf("client socket response: %d\n", client_socket);
    perror("socket");
    send(client_socket, http_header, sizeof(http_header),0);
    close(client_socket);

}

    
    return 0;

}

index.html

<html><body>welcome to the HTTP Server!</body></html>

Solution

  • I think you're pretty close to getting it working. The reason curl is complaining is because it's expecting you to have supplied a Content-Length header. You can do this by updating your existing code as follows:

        char response_data[1024];
        fgets(response_data, 1024, html_data);
    
        size_t message_length = strlen(response_data);
    
        char http_header[2048];
        snprintf(http_header, sizeof(http_header), "HTTP/1.1 200 OK\r\nContent-Length: %zu\r\n\r\n", message_length);
        strcat(http_header, response_data);
    

    You also need to update your send code to only send the length of the response string.

        send(client_socket, http_header, strlen(http_header),0);
    

    You still have some issues with your error checking as mentioned in the comments, but at least with these changes curl should be happy.


    While what I mentioned above is the minimal headers that will satisfy curl, there are others that you need to add to make you code conform to Hypertext Transfer Protocol -- HTTP/1.1

    Connection: close
    Content-Type: text/html