How correctly and without crutches to read data from a socket?
Before that, I wrote in C ++ / Qt and there was a wonderful QTcpSocket :: readAll () method that returned everything that was transferred to the socket. In Sharp, only StreamReader.ReadToEnd () saw from this, but it throws out an exception saying this object does not support or something like that).
In Google, I found only methods that offer to catch the ending of data using try {} catch {}, but it seems to me that these are just rude curved crutches.
In general, I will be glad to any help on this issue.
PS: And in Qt everything was so simple, clear and logical ...
|
1 answer
If you really need to read everything that has come (it is rarely needed, in fact), then you can use the Socket.Available property. After receiving the number of bytes you can select the buffer of the desired size and read everything that is ready.
In Java, I have had to work with sockets more than once and I don’t remember that I have needed it at least once .. the general scheme is always the same: I make a buffer and read it until it ends. So I don’t understand why you need to read all.
As for try / catch, it really looks like a crutch. Do not get fooled by such tips.
- I just need everything. I saw this property, but did not understand how it works <pre> <code> TcpClient c = m_listener.AcceptTcpClient (); Console.WriteLine (c.Available); NetworkStream ns = c.GetStream (); byte [] bytes = new byte [5]; ns.Read (bytes, 0, bytes.Length); Console.WriteLine (c.Available); </ code> </ pre> In the first case, 0 is output, and in the second, how many bytes are left. You can of course count one byte, and then the rest, but this again looks like a crutch ... Socket s = ...; s.Available also writes 0 ... In the example from MSDN, zeroes are also output ... - AlexDenisov
- Some kind of bug. Or maybe it is not immediately updated somehow .. maybe, after reading it is updated. Why do you need it? You will still have to process the stream in parts. Reading to the end is always very conditional: you can never know if there was an end or if a couple more bytes will arrive (unless, of course, the protocol does not inform you, or the stream has not closed). - cy6erGn0m
- Hmm ... Something is wrong with the local markup, sent everything was beautiful, and now it is clumsily displayed ... Yes, perhaps that's true, I will do so, but I thought that there was something like the same readAll () .. So how do you know if the stream is really over? - AlexDenisov
- Understand that the meaning of readAll is not there. It is an illusion that you read everything. In fact, it makes no difference whether you read in fixed blocks of the size you specify or in several parts of an unknown size beforehand. You still have to process the stream in parts and there is never any certainty that readAll read everything - cy6erGn0m
- oneThat you are lucky. I can give you an example: suppose the client sends the text in one bundle: "AAABBB", and readAll is said on the server. The package is coming .. and suddenly some kind of crap happens .. some kind of fragmentation or something else .. and .. the package breaks into two .. and the second one is behind .. as a result, readAll will read you "AAA" .. and "BBB "will come in a couple of milliseconds .. to read this part, you would have to call readAll again .. but then it doesn't matter if you requested a specific number of bytes (for example, 512 bytes) or asked readAll - cy6erGn0m
|