tags:

views:

45

answers:

2

I am writing a usenet newsreader, and calling the XOVER id- message to get all articles in a group.

If i am using this code, i am only getting the first 5kB of the response:

        while((read = _networkStream.Read(buffer, 0, 5000)) > 0)
        {
            ret += Encoding.ASCII.GetString(buffer, 0, read);
            if(read < 5000)
                break;

        }

But if i add Thread.Sleep(100); into the loop, i get the whole list.

Can i do this another way?

+3  A: 

The check for read < 5000 will break out of the loop immediately after you do not get a full buffer. It is not at all guaranteed that you get a full buffer's worth of data, so you shouldn't have that part there at all. Just keep the check for read being > 0 in the while condition and things work correctly, since the returned value being positive is the defined indication for a successful read.

And the reason why it works when you include the sleep is that by sleeping you let the underlying incoming data buffer fill up enough that on the next round there is enough data for a full buffer.

And since in NNTP connections are used for multiple commands, you will need to recognize the termination of the data at the application level; the socket functions will not help you, since they won't understand how NNTP delimits messages. The specification of the XOVER command says that "Once the output is complete, a period is sent on a line by itself." So you will need to parse the response inside your loop (splitting it into lines since NNTP is line-oriented), and when you encounter a period on a line by itself, break out of the loop then.

jk
This doesn't work. While the string is complete. It is stuck on `_networkStream.Read(buffer, 0, 5000)` when the last buffer of data is read. It never exits the loop.
Erik
@Erik: Sorry, I overlooked you were doing NNTP. Answer expanded to suggest how to do this with such a line-oriented persistent-connection protocol.
jk
Adding a ret.EndsWith(".\r\n") solved the problem.
Erik
@Erik: That will break when a buffer ends with `".\r\n"` by accident. You need to check for `"\r\n.\r\n"` and also remember that that string might be split across two (or more) iterations of the loop, so you need to remember some information from the previous iteration(s).
jk
Yes, i have corrected that, as it happened.
Erik
A: 

why break when read < 5000? you definitely should break only when read <=0. sorry, didn't notice Read(buffer, 0, 5000)) > 0.

Benny