Search code examples
cstringsockets

TCP Socket - printing all chars of a string that are not \n in C not working


I have a recv function that I'm using for receiving socket(here It's a HTTP GET request). I simply want to remove '\n' of the request so I can work more easily.

Code:

void receiveHTTP(int clientSockfd, char *buff, size_t __n, int __flags)
{
    int bytes = recv(clientSockfd, buff, __n, __flags);
    printf("%s",buff);
    for (int i = 0; i < strlen(buff); i++)
    {
        if (buff[i] != '\n'){
            printf("%c", buff[i]);
        }
    }
}

Output:

GET /1 HTTP/1.1
user-agent: got (https://github.com/sindresorhus/got)
accept-encoding: gzip, deflate, br
cookie: PHPSESSID=37f65v1f9dcbmq3nbvqvev6bf4
Host: localhost:8080
Connection: close

Which is exactly buff, but the no new line version of it is not being printed. What is the reason?

Thanks in Advance.


Solution

  • You are completely ignoring the return value of recv(), which tells you exactly how many chars it actually put into buff.

    The %s specifier of printf() expects a null-terminated string, but buff is not guaranteed to be null-terminated. You should pass the return value of recv() to printf() so it knows how many chars it can safely print.

    Likewise, you don't need strlen() since you already know how many chars are in buff.

    You are printing the contents of buff twice, is that what you really want?

    Lastly, HTTP uses \r\n for line breaks, not just \n by itself.

    Try this instead:

    void receiveHTTP(int clientSockfd, char *buff, size_t __n, int __flags)
    {
        int bytes = recv(clientSockfd, buff, __n, __flags);
        if (bytes <= 0) return;
    
        // prints the whole thing...
        printf("%.*s",bytes,buff);
        // or: fwrite(buff, bytes, 1, stdout);
        // or: write(STDOUT_FILENO, buff, bytes);
    
        // prints everything ignoring line breaks...
        for (int i = 0; i < bytes; ++i)
        {
            if (buff[i] != '\r' && buff[i] != '\n'){
                printf("%c", buff[i]);
            }
        }
    }
    

    Also, keep in mind that this function is just reading arbitrary bytes from the socket, it is not actually interpreting the structure of the HTTP protocol. HTTP can send a mix of ASCII text and binary data, which this code is not differentiating.