最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin0浏览0评论

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 ()
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.

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/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.

Share Improve this question edited Jan 31 at 17:36 Mehan Alavi asked Jan 31 at 17:18 Mehan AlaviMehan Alavi 3274 silver badges19 bronze badges 8
  • 2 The HTTP header uses \r\n at the end of every line. I assume that you also want to remove the \r? – Andreas Wenzel Commented Jan 31 at 17:21
  • 3 strlen(buff) only works for string. Use bytes. That's what its for. – stark Commented Jan 31 at 17:24
  • 1 Are you sure buff is actually a string, i.e. it is null-terminated? – John Gordon Commented Jan 31 at 17:25
  • 1 Using the %s conversion format specifier requires a pointer to the first character of a null-terminated string. The data written by recv is not guaranteed to be null-terminated. Therefore, I suggest that you use printf("%.*s",bytes,buff); instead. – Andreas Wenzel Commented Jan 31 at 17:25
  • 3 There is no guarantee that you have received all of your data. With TCP/IP, you may receive one byte, you may receive all of the bytes. You need to check the return value, and when the string is complete (i.e. the newline has been received), then check the string. – Brad Lanam Commented Jan 31 at 17:27
 |  Show 3 more comments

2 Answers 2

Reset to default 4

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.

As @AndreasWenze Pointed out The HTTP newline is actually \r\n not \n.

Updated 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 < bytes; i++)
    {
        if (buff[i+1] != '\n' && buff[i] != '\n' ){
            printf("%c", buff[i]);
        }
    }
    printf("\n");
}

Output:

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

GET /1 HTTP/1.1user-agent: got (https://github/sindresorhus/got)accept-encoding: gzip, deflate, brcookie: PHPSESSID=37f65v1f9dcbmq3nbvqvev6bf4Host: localhost:8080Connection: close

Which is correct.

发布评论

评论列表(0)

  1. 暂无评论