Daniel
Daniel

Reputation: 385

C# performance methods of receiving data from a socket?

Let's assume we have a simple internet socket, and it's going to send 10 megabytes (because I want to ignore memory issues) of random data through. Is there any performance difference or a best practice method that one should use for receiving data? The final output data should be represented by a byte[]. Yes I know writing an arbitrary amount of data to memory is bad, and if I was downloading a large file I wouldn't be doing it like this. But for argument's sake let's ignore that and assume it's a smallish amount of data. I also realise that the bottleneck here is probably not the memory management but rather the socket receiving. I just want to know what would be the most efficient method of receiving data.

A few dodgy ways can think of is:

  1. Have a List and a buffer, after the buffer is full, add it to the list and at the end list.ToArray() to get the byte[]

  2. Write the buffer to a memory stream, after its complete construct a byte[] of the stream.Length and read it all into it in order to get the byte[] output.

Is there a more efficient/better way of doing this?

Upvotes: 5

Views: 3007

Answers (4)

Pat
Pat

Reputation: 16891

Well, Jon Skeet's answer is great (as usual), but there's no code, so here's my interpretation. (Worked fine for me.)

using (var mem = new MemoryStream())
{
    using (var tcp = new TcpClient())
    {
        tcp.Connect(new IPEndPoint(IPAddress.Parse("192.0.0.192"), 8880));
        tcp.GetStream().CopyTo(mem);
    }
    var bytes = mem.ToArray();
}

(Why not combine the two usings? Well, if you want to debug, you might want to release the tcp connection before taking your time looking at the bytes received.)

This code will receive multiple packets and aggregate their data, FYI. So it's a great way to simply receive all tcp data sent during a connection.

Upvotes: 1

feroze
feroze

Reputation: 7594

What is the encoding of your data? is it plain ASCII, or is it something else, like UTF-8/Unicode?

if it is plain ASCII, you could just allocate a StringBuilder() of the required size (get the size from the ContentLength header of the response) and keep on appending your data to the builder, after converting it into a string using Encoding.ASCII.

If it is Unicode/UTF8 then you have an issue - you cannot just call Encoding..GetString(buffer, 0, bytesRead) on the bytes read, because the bytesRead might not constitute a logical string fragment in that encoding. For this case you will need to buffer the entire entity body into memory(or file), then read that file and decode it using the encoding.

Upvotes: 0

Jeremy
Jeremy

Reputation: 46350

You could write to a memory stream, then use a streamreader or something like that to get the data. What are you doing with the data? I ask because would be more efficient from a memory standpoint to write the incoming data to a file or database table as the data is being received rather than storing the entire contents in memory.

Upvotes: -1

Jon Skeet
Jon Skeet

Reputation: 1500515

Just write to a MemoryStream and then call ToArray - that does the business of constructing an appropriately-sized byte array for you. That's effectively what a List<byte> would be like anyway, but using a MemoryStream will be a lot simpler.

Upvotes: 3

Related Questions