5
\$\begingroup\$

I've noticed that there are several ways of sending data through a TCP stream. I want to do it the fastest way in terms of latency.

One method I became aware of is with a binary writer:

using (MemoryStream ms = PrintWindow(process))
{
    writer.Write((int)ms.Length);
    writer.Write(ms.GetBuffer(), 0, (int)ms.Length);
}

And to receive it:

Image.FromStream(new MemoryStream(reader.ReadBytes(reader.ReadInt32())));

It writes the size for reference, then takes the data.

For the other method, which is a bit sensitive, it seems that it can easily fail if the image changes for some reason:

using (MemoryStream ms = PrintWindow(process))
{    
    tcp.GetStream().Write(ms.GetBuffer(), 0, tcp.SendBufferSize); 
}

And to receive it:

byte[] b = new byte[tt1.ReceiveBufferSize];
tt1.GetStream().Read(b, 0, tt1.ReceiveBufferSize);
Image.FromStream(new MemoryStream(b));

I've found this with trial and error. But, as I've said, it's very sensitive and can cause an error if the image changes in a certain way. I'm not absolutely sure why, though.

Which of these is the fastest? In my view, writing with just the stream should be faster than with some special writer.

The error I get when using the second method seems to occur when the data is very low. For example: a black or near-black picture. If anyone knows how to solve this, please let me know.

It seems that I need to have the TCP Send and Receive buffer at least as big as the largest file for it to work, so I've increased it by x128. I'm not sure if that's a good idea or not, but from my understanding, the only thing it does is allocate more RAM. Then again, I think it's probably because I set the byte size to the buffer size.

\$\endgroup\$
  • \$\begingroup\$ there are various ways of checking the incoming data. And of reading and writing.. eg readline, readexisting, read.. which all have their advantages etc.. You have not indicated how you are formating start and stop bits, and how you are listening for data. how you manage the flow of reading data, the way you read it and the way you format loops in your code will make a difference to performance \$\endgroup\$ – Yvette Colomb Aug 6 '13 at 17:30
  • \$\begingroup\$ I remember something about my PDF application where you set the Buffer size...let me get back to you \$\endgroup\$ – Malachi Nov 8 '13 at 20:10
5
\$\begingroup\$

If you are looking for ways to optimize your application - you are clearly looking at the wrong place, at least in my opinion. BinaryWriter is a simple wrapper around actual stream. All it does is it converts simple types to byte arrays and writes those to stream. Ofc it is slower, as any other wrapper, but not that much slower. In real life this difference can be ignored.

If writing to NetworkStream is your main performance issue, then consider wrapping it with BufferedStream.

If it isnt, and you are simply curious... then you can always use disassembler to see whats inside BinaryWriter.Write method for yourself.

\$\endgroup\$
  • \$\begingroup\$ Hmm, thought it was good to write stuff like this, as many ask stuff like this. But guess it´s wrong then, sorry. But from what you wrote, i get that as close to the stream you are, the faster it get´s. Meaning writing directly is faster than going around to write to it. \$\endgroup\$ – Zerowalker Aug 6 '13 at 13:37
  • 1
    \$\begingroup\$ @Zerowalker, nah, there is nothing wrong with curiosity. And your logic is correct. However if you are going to blindly follow it - you will end up having one mega-object with one mega-method containing all of your application's logic implemented using API calls. I would not say "worth it" looking at such code, and neither would you, im sure. Even though it will indeed run faster then the same code refactored using common OOP practices and patterns (wrapper being one of such patterns.) \$\endgroup\$ – Nikita B Aug 6 '13 at 14:14
  • \$\begingroup\$ Well that´s good. And well at this application, i really need to get the most out of it, especially latency, 1ms here and there is important. Normally i wouldn´t care that much as long as it works well. But that being said. Binarywriter/reader is faster in my tests weird enough;S \$\endgroup\$ – Zerowalker Aug 6 '13 at 15:25
  • \$\begingroup\$ That's probably because you are working with streams in some wierd way :) Yet another reason to use dedicated writers :) \$\endgroup\$ – Nikita B Aug 7 '13 at 5:50
  • \$\begingroup\$ Probably, but would like to get it to work. It´s weird that there isn´t a direct way to write a file, and when it´s done, send a "Cancel". I found something in WriteAsync, CancellationToken, but it seems it´s something else though. \$\endgroup\$ – Zerowalker Aug 7 '13 at 7:25
2
\$\begingroup\$
using (MemoryStream ms = PrintWindow(process))
{    
    tcp.GetStream().Write(ms.GetBuffer(), 0, tcp.SendBufferSize); 
}

This is very very bad. Do NOT do this. It is going to try and write tcp.SendBufferSize bytes across the stream. But you've made no attempt to be sure that's correct. You could be sending too many bytes, or too few bytes. You've already noted that it fail randomly, but you've papered over the real problem.

Performance wise, its not going to give you an advantage. When it works, you are sending a large amount of bytes across the network you aren't using. That's going to be a serious performance problem.

\$\endgroup\$
  • \$\begingroup\$ Yeah notices how stupid this was. I am trying to do something like the first, but without using a "3rd" party writer. But i don´t know how to tell the other client that the data has ended. \$\endgroup\$ – Zerowalker Aug 6 '13 at 17:27
  • \$\begingroup\$ @Zerowalker, the person who wrote the 3rd party writer was probably way more experienced then you. You've got no reason to assume that you could do a better job then him. \$\endgroup\$ – Winston Ewert Aug 6 '13 at 17:34
  • \$\begingroup\$ probably, but the performance between the different ways to do this task of just sending an image is quite large. So that´s why i want to do it the simplest way, without any special stuff going on. That being sad, i am not thinking i could write a writer that´s better than probably any that exist with my skills. \$\endgroup\$ – Zerowalker Aug 6 '13 at 17:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.