views:

58

answers:

3

This loop is supposed to take data from a socket line by line and put it in a buffer. For some reason, when there is no new data to return, recv returns the last couple lines it got. I was able to stop the bug by commenting out the first recv, but then I cant tell how long the next line will be. I know it's not a

while(this->connected){
    memset(buf, '\0', sizeof(buf));
    recv(this->sock, buf, sizeof(buf), MSG_PEEK);           //get length of next message
    ptr = strstr(buf, "\r\n");
    if (ptr == NULL) continue;
    err = recv(this->sock, buf, (ptr-buf), NULL);    //get next message

    printf("--%db\n%s\n", err, buf);

    tok[0] = strtok(buf, " ");
    for(i=1;tok[i-1]!=NULL;i++) tok[i] = strtok(NULL, " ");

//do more stuff
}
+1  A: 

The manual states:

MSG_PEEK This flag causes the receive operation to return data from the beginning of the receive queue without removing that data from the queue. Thus, a subsequent receive call will return the same data.

So I think you're getting the correct behavior, but perhaps expecting something else.

unwind
I have 2 calls to recv, the second one has flags set to 0 (not MSG_PEEK). I'm looking for "\r\n" in what I get from the first recv, then only taking until the "\r\n" on the second recv. I found my problem as I was writing that, though. I needed to add 2 to the length of the second recv so I'd take the "\r\n".
anon
+1  A: 

Your problem is that when you use recv with MSG_PEEK, you are giving recv the whole size of your buffer, if there are two lines already there, like "HELLO\r\nHELLO\r\n" it will read them into your buff.

ptr would point to the first \r\n, then you call recv with (ptr - buff) which will make recv to read only the first HELLO, into buf, but since you already READ that info into buff, you will process the two lines, but leaving \r\nHELLO\r\n in your queue, because you did not fully read them.

Next time you would peek into it and have info hanging that you already processed, leading you to believe that you are getting repeated data.

(I hope I wrote this clear enough, it is a very confusing bug you got there :)

Francisco Soto
A: 

I needed to add 2 to the length of the second recv so I'd take the "\r\n". Otherwise, it sees the first "\r\n" and thinks the line of the end is buf[0].

anon