Tcp / IP socket connections in .NET.

For my current project, I need to request XML data through a tcp / ip socket connection. For this, I use the TcpClient class:

Dim client As New TcpClient() client.Connect(server, port) Dim stream As NetworkStream = client.GetStream() stream.Write(request) stream.Read(buffer, 0, buffer.length) // Output buffer and return results... 

Now it works fine and dandy for small answers. However, when I start receiving large blocks of data, it seems that the data is getting through the socket connection in bursts. When this happens, calling stream.Read only reads the first packet, and thus, I skip the rest of the response.

What is the best way to deal with this problem? Initially, I tried to just loop around until I had a valid XML document, but I found that between the stream. Reading causes the underlying thread to sometimes shut down, and I skip the last piece of data.

+4
source share
4 answers

You create a read loop.

Stream.Read returns an int for the bytes that it has read so far, or 0 if the end of the stream has been reached.

So its kind of:

 int bytes_read = 0; while (bytes_read < buffer.Length) bytes_read += stream.Read(buffer, bytes_read, buffer.length - bytes_read); 

EDIT: Now the question is how do you determine the size of the buffer. If your server sends the size first, that's fine, you can use the snippet above. But if you need to read until the server closes the connection, you need to use try / catch (this is a good idea, even if you know the size), and use bytes_read to determine what you got.

 int bytes_read = 0; try { int i = 0; while ( 0 < (i = stream.Read(buffer, bytes_read, buffer.Length - bytes_read) ) bytes_read += i; } catch (Exception e) { //recover } finally { if (stream != null) stream.Close(); } 
+3
source

Reading does not guarantee full reading of the stream. It returns the number of valid bytes to read and 0 if there are no more bytes to read. You must continue the loop to read all the data from the stream.

+2
source

This is a possible way to do this and get the response line of the answer. If you need an array of bytes just save ms.ToArray ().

 string response; TcpClient client = new TcpClient(); client.Connect(server, port); using (NetworkStream ns = c.GetStream()) using (MemoryStream ms = new MemoryStream()) { ns.Write(request); byte[] buffer = new byte[512]; int bytes = 0; while(ns.DataAvailable) { bytes = ns.Read(buffer,0, buffer.Length); ms.Write(buffer, 0, bytes); } response = Encoding.ASCII.GetString(ms.ToArray()); } 
0
source

I highly recommend you try WCF for such tasks. This gives you, after a not so steep learning curve, many advantages over the raw socket connection. For this task, I agree with the previous answers, you should use a loop and dynamically allocate memory as needed.

0
source

Source: https://habr.com/ru/post/1277453/


All Articles