0

I need to read in only the values of a header that terminate with \r\n\r\n

Something like GETFILE OK 1024\r\n\r\n <content>

I'm trying to get the first \r\n and then get the next pair in a subsequent recv call. The call to this function is: read_in_header(gfr, headerRecvBuff, 1);

Issue: The logic in the while referring to \n is completely ignored, or does not show any matches, when I know they exist. Is this the right way to compare the char newline?

int read_in_header(gfcrequest_t *gfr, char *buf, int len) {
char *s = buf;
int slen = len;
int c = 0;
int count = 0;
//get the first \r\n pair
do {
    c = recv(gfr->client_fd, s, slen, 0);
    printf("checking to see what s has now: %s\n", s);
    count += c;
} while ((c > 0) && (s[count - 1] != '\n'));

//get the second \r\n pair
count = 0;
do {
    c = recv(gfr->client_fd, s, slen, 0);
    printf("checking to see what s has now: %s\n", s);
    count += c;
} while ((c > 0) && (s[count - 1] != '\n'));

printf("checking to see what s has now: %s\n", s);


if (c < 0) {
    return c;
} else if (c == 0) {
    puts("Time to disconnect, the server is done.");
    //total bytes received should not include header length
    gfr->totalbytesReceived -= gfr->headerbytes_received;
    return 0;
} else {
    s[c - 1] = '\0';
}
gfr->totalbytesReceived += count;
return c;
}
Jud
  • 1,324
  • 3
  • 24
  • 47
leroneb
  • 75
  • 7
  • 1
    If the data is sent as a TCP stream, you can not rely on boundaries between data sent. It's a **stream**. If you try to receive 10 bytes, you may get 2 - or there may be 2000 bytes waiting for you to read. – Andrew Henle Jun 08 '15 at 20:02
  • 1
    Fyi, you're always reading data into the beginning of the memory addressed by `buf`. (aka `s` in this code). But `s[count-1]` uses an *accumulated* counter, not the number of octets read on the last `recv` call. In short, on a successful `recv` where `c > 0` the data read will be in `s[0..c-1]`. I don't see why you're using `count` to subscript `s`. – WhozCraig Jun 08 '15 at 20:15
  • Yes, at first I thought recv would append to the buffer, but missed that s would be a pointer to the start of the buffer each time. I decided to use a combination of what you said and the logic from @ryyker – leroneb Jun 09 '15 at 19:22

1 Answers1

1

Regarding Is this the right way to compare the char newline?

Since s is a buffer (not a single char), for the first loop the comparison method can be changed to

while ((c > 0) && (strstr(s, "\r\n") == NULL));

To require both "\r" & "\n" are there. This takes advantage of string searching to check both values are present in one line.

resulting in:

do {
    c = recv(gfr->client_fd, s, slen, 0);
    printf("checking to see what s has now: %s\n", s);
    //  count += c; //not needed
} while ((c > 0) && (strstr(s, "\r\n") == NULL));

If you decided to capture the line that has all 4, i.e. \r\n\r\n, then make that the argument of the comparison.

One side note, unless you have set socket options to non-blocking, recv() is a blocking call. Look into how to set a socket to non-blocking

Community
  • 1
  • 1
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • I had length to be read in as 1 byte as well, but understood that on each iteration, the buffer would be overridden. I added non-blocking to the client file descriptor socket(client_fd) on creation, and i'm using the condition in your loop, but just with "\r\n\r\n" as per our protocol. – leroneb Jun 09 '15 at 19:25