How to speed up slow / slow Windows Phone 7 (WP7) TCP Socket Transmission?

Recently, I started using the System.Net.Sockets class introduced in the Mango WP7 release and, as a rule, enjoyed it, but noticed a discrepancy in the latency of data transfer in debug mode and works fine on the phone.

I am writing a โ€œremote controlโ€ application that transfers one byte to a local server on my local network via Wi-Fi when a user enters a button in the application. Ergo, perceived responsiveness / timeliness of the application is very important for a good user experience.

When the phone is connected to the computer via a USB cable and launches the application in debug mode, the TCP connection seems to send packets as fast as the buttons on the user buttons.

When the phone is disconnected from the PC, the user can use up to 7 buttons (and thus send 7 commands with 1 byte payload before sending all 7 bytes.) If the user pressed the button and waited a bit between the taps, it seems that there is a latency of 1 second .

I tried the Socket.NoDelay parameter for both True and False, and it doesn't seem to matter.

To find out what was going on, I used a packet analyzer to see what the traffic looked like.

  • When the phone was connected via USB to a PC (which used a Wi-Fi connection), each individual byte was in its own packet with an interval of ~ 200 ms.

  • When the phone worked on its own Wifi connection (disconnected from USB), the bytes still had their own packets, but they were all grouped into packets of 4 or 5 packets, and each group was ~ 1000 ms from the next.

btw, the ping time on my wifi network on the server is 2 ms, as measured from my laptop.

I understand that buffering โ€œsendsโ€ together probably saves the phone energy, but is there a way to turn off this โ€œdelayโ€? Application responsiveness is more important than energy saving.

+7
source share
6 answers

This is a really interesting question! I am going to drop my 2 cents, but please keep in mind that I am not an expert on System.Net.Sockets on WP7.

First, performance testing in the debugger should be ignored. The reason for this is that the extra overhead of stack trace logging always slows down applications, regardless of the OS / language / IDE. Applications must be profiled for performance in release mode and disconnected from the debugger. In your case its slower is disabled! Good, so try optimizing this.

If you suspect that packets are buffered (and this is a reasonable assumption), try sending a larger packet? Try linearly increasing the packet size and measurement delay. Could you write a simple microprofile in the code on the device, i.e. Using the DateTime.Now or Stopwatch class to record the delay time and packet size. Plotting a graph can give you a good idea of โ€‹โ€‹the correctness of your theory. If you find that packets with 10 bytes (or even 100 bytes) will be sent instantly, I would suggest simply increasing the amount of data to transmit. This is a lame hack that I know, but if it didn't break ...

Finally, you say you are using TCP. Can you try instead of UDP ? TCP is not intended for real-time exchange, but rather for accurate communication. UDP by contrast is not checked for errors, you cannot guarantee delivery, but you can expect faster (lighter, lower latency) from it. Networks such as Skype and online games are built on UDP rather than TCP. If you really need a receipt confirmation, you can always create your own micro-protocol via UDP, using your own Cyclic Redundancy Check for error checking and the Request / Reply (confirmation) protocol .

Such protocols exist, see Reliable UDP , discussed in this previous question . There is a Java-based RUDP implementation, but I'm sure some parts can be ported to C #. Of course, the first step is to check if UDP really works!


Found this previous question that discusses the issue. Perhaps the problem is Wp7? Poor UDP performance with Windows Phone 7.1 (Mango)

It would still be interesting to know if increasing packet size or switching to UDP works


ok, so not a single sentence worked. I found this description of the Nagle algorithm, which groups packages as they are described. Installing NoDelay should help, but, as you say, does not.

http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.nodelay.aspx

Besides. See this previous question where Keepalive and NoDelay were turned on / off to manually clear the queue. His proof is anecdotal, but worth a try. Can you answer and edit your question to post more recent results?

Socket "Flush" temporarily disabling NoDelay

+2
source

Andrew Burnett-Thompson has already mentioned this here, but he also wrote that this did not work for you. I do not understand, and I do not see WHY. So let me explain this problem:

A Nagle algorithm was developed to avoid a scenario where many small packets were to be sent over a TCP network. Any current TCP stack stack allows you to use the Nagle algorithm by default!

Because: TCP itself adds a significant amount of overhead to any data transfer material that passes through an IP connection. And applications usually don't care about sending their data in an optimized way over these TCP connections. So, after the Nagle algorithm, working inside the TCP stack of the operating system, does a very good job.

The best explanation of Nagle's algorithm and its background can be found on Wikipedia .

So, your first attempt: disable the Nagle algorithm for your TCP connection by setting the TCP_NODELAY option to the socket. Did this solve your problem already? Do you see any difference whatsoever?

If this is not the case, then give me a sign, and we will take a closer look at the details.

But please look twice at these differences: check the details. Perhaps in the end you will understand how things actually work in your TCP / IP-Stack OS.

+2
source

Most likely, this is not a software problem. If the phone uses WiFi, the delay can exceed 70 ms (depending on where the server is, how much bandwidth it has, how busy it is, interference to the access point and distance from the access point), but most of the delay is just WiFi. Using GMS, CDMA, LTE or any other technology used by the phone for cellular data is even slower. I would not think that you will get much less than 110 ms on a cellular device if you do not stand under the mesh tower.

+1
source

It looks like your reads / writes are buffered. You can try to set the value of the NoDelay property on Socket to true, you can also consider configuring the sizes of the send and receive buffer. Reduced responsiveness can be a byproduct as there is not enough wifi traffic, I'm not sure if MTU tuning is an option, but decreasing MTU can improve response time.

All these are just low-bandwidth solution options, if you intend to dig up megabytes of data in any direction, you will need larger Wi-Fi buffers large enough to compensate for transmission latency, usually in the 32K-256K range.

var socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { NoDelay = true, SendBufferSize = 3, ReceiveBufferSize = 3, }; 

I have not tested this, but you get the point.

+1
source

Have you tried setting SendBufferSize = 0? In "C", you can disable winsock buffering by setting SO_SNDBUF to 0, and I assume that SendBufferSize means the same in C #

+1
source

Have you accidentally used the Lumia 610 and the mikrotik access point?

I ran into this problem and the Lumia 610 turned off the Wi-Fi radio as soon as the last connection was closed. This added noticeable delay, for example, compared to the Lumia 800. All connections were affected - just switching Wi-Fi made all applications faster. My administrator says that some functions of mikrotiks were not supported at that time in combination with WMM settings. Oddly enough, most of the other phones did a fine job, so we blamed the 610 for cheap in the beginning.

If you can still replicate the problem, I suggest trying the following:

  • open another connection in the background and ping all the time.
  • use 3g / gprs instead of wifi (requires exposing your server to the internet)
  • use another (or updated) phone.
  • use another (or updated) AP
0
source

All Articles