Huge UDP delay/lag with Android - android

I'm working on an Android application which sends/receives a high volume of UDP traffic to a Windows endpoint over a WLAN (and no, I can't use TCP).
The problem is that when I ramp up the traffic, I begin to see HUGE delays between when I call sendto (the app is written with the NDK) and when I see the packet arrive at the Windows endpoint. In the neighborhood of 10 seconds! The same thing happens in reverse too: I see huge delays between the packet being sent by the Windows endpoint and being picked up by recvfrom().
Changing SO_SNDBUF has no effect, so I don't think it's an issue with the application-level buffering control.
I've verified that the problem exists on a variety of Android devices, so I don't think it's an issue with the hardware/wireless drivers
Using a sniffer and correlating the timestamps, I confirmed that the delay is occurring between calling sendto() and the packet being sent from the Android device, so the buffering isn't happening in the AP or Windows endpoint
So at this point I'm all but out of ideas. The facts would lead me to believe that the buffering is happening on the Android OS layer, but 10 seconds of 10Mbps traffic? That seems too high to be feasible for an OS where memory footprint is such a huge concern.
Also, if the issue is that I'm sending data too fast and overwhelming the OS, then I would expect sendto() to return ENOMEM or ENOBUFS... But there are no indications that anything is wrong on the Android application level.
So my question is: what's causing this delay? And is there a way to mitigate it, or do I need to alter my application to have longer timeouts or some way of detecting this condition before it gets bad?

You are sending too much.. how much are you sending? 10Mbps is definitely way too high. Bear in mind:
Every UDP datagram you send has an additional 28 byte header (UDP + IP over IPv4)
Connection link speeds are theoretical maximum limits that you will never be able to achieve
The Phone OS could be limiting you, Phone OS's need to conserve battery and try to minimise socket comms to do so.
OR
You say your CPU is at 20%, how many cores do you have - you could be maxing out the core that is doing the sending, i.e. processing speed is the bottleneck.

For people with the same problem:
Try reusing the DatagramSocket. That solved it for me.

I've seen reports of very similar behavior on the linux-rt list lately, which may be related.
http://comments.gmane.org/gmane.linux.rt.user/10163
For a several months I was haunted with spurious jitter, detected on
UDP messages - multicast UDP messages where received on originating
node without any delay, but on other nodes a delay in range of 10s of
milliseconds was detected. Simply, it looked like a message was stuck
in kernel before finally getting transmitted.
Finally, thanks to LTTng tool, I was able to locate the problem down to
this peace of code in net/sched/sch_generic.c:
There appears to be a locking issue on transmit that causes the tx stall.

Related

Google Nearby Connections 2.0 capabilities

I am evaluating Google Nearby connections2.0 more specifically evaluating the synergy effect of it. For this I am evaluating it against Wifi, Bluetooth and BLE in totally offline scenario, without any router.
Scenario
One device is advertising, all others (8 devices in total) are discovering. On successful connection, I am sending simple Files of 20B, 200B and 33KB sizes for 30 secs straight to each connected device.
I am using android Samsung S6 SM-G920F devices with android version: 6.0.1 and playservices version 12.8.74
I have following issues/questions
Q1: First of all at max 3 to 4 devices could be connected simulatenously more than this results into disconnect event of other devices. Even if only 3 devices are connected, and I am continuously sending message for 30seconds, one of them disconnected ? In simpler words, cannot sustain connectivity with any device for more than 45 secs. usually disconnection occur between 25 - 45 secs
Q2: I cannot send message/file continuously for 30 seconds like we can do with the Wifi like this
While(30sec){
bluetoothSocket.outputStream.write(bytes)
}
Because if I try to do this then I got the exception of too much work.I have to wait for the the callback in onTransferPayLoadUpdate()
Q3: If I try to send the file of 1MB or more to other peers, peer received the file successfully in onPayloadReceived callback but server/sender receive the successful status after too much delay. In my case it's between 1 mins to 5 mins after client callback. And I cannot send new file until I got the success callback on server. If I try to send it before getting the callback, nothing happens. Literally nothing. So In essence I can only send file of 1MB once then I have to resent both the devices to send another file.
This should be broken up into 3 separate questions. It helps future developers search easier. So if you get the time to do that, let me know and I'll split up my answer as well. But anyway, let's get into it!
A1: Nearby Connections has 3 separate strategies. The more limited the strategy, the more types of mediums we can use. So with that in mind, and with no router involved, P2P_CLUSTER will only use Bluetooth. It's the most general strategy, so it has the fewest mediums available.
All Android devices use mobile Bluetooth chips, which are unfortunately weak (but small and power sensitive), and that causes them to have a theoretical 7 device limit but a practical 3~4 device limit. To make things worst, that limit is eaten up by smart watches and paired headphones as well. That's why you're running into problems.
P2P_STAR and P2P_POINT_TO_POINT are both much more limited, because you can't connect in any direction. You need to choose who the host is beforehand and have everyone scan for and connect to that host. But you get the added benefit of WiFi hotspots, which have higher bandwidth and a larger number of simultaneous devices supported. I've seen 7 devices happily connected to a Lollipop device.
If you want to go beyond that, into the 10s and 100s, and a router isn't available, you'll have to build a mesh network. I can link you to examples of how to do that if you're interested. We don't offer support for that within Connections, but others have built meshes on top of us so we can point you in the right direction.
A2: Can you include a stack trace of the error you're seeing? Payload.Type.STREAM was built for continuously sending data. The other payload types should also work too, baring some rare but potential issues like BYTE payloads filling up the phones RAM.
A3: Both devices need to wait for onPayloadTransferUpdate(SUCCESS). onPayloadReceived is only a header, and means that there's an incoming file or stream but that the data hasn't been received yet. For byte payloads, we actually send the full byte payload inside the header so that's the only time data is immediately available.

Why does Android Bluetooth stop receiving bytes after a few minutes?

I'm having trouble maintaining a Bluetooth connection (from Android to a device I'm developing) for longer than a few minutes.
The scenario is:
Device is paired successfully.
Device transmits to Android for somewhere between 1-7 minutes (varies by device or possibly Android version).
Android stops receiving bytes although device is still transmitting.
So: why does Android BT stop receiving?
This is very similar to the issue/observation described in bboydflo's answer to this question:
Application using bluetooth SPP profile not working after update from Android 4.2 to Android 4.3
Some more background:
The BT device I'm working with continually emits measurement packets containing ~200 characters, once per second. I am certain that the device-side is still transmitting when the issue occurs.
This sympom happens in my app on two Android devices: an Android 5.0.1 Acer tablet, and an Android 7.1.1 Moto Play X
I've tested with an app called Serial Bluetooth Terminal. This app does not experience the same issue; the connection is stable for as long as I've tested. Therefore, this issue is probably caused by something in my application code.
I've seen various responses to Android BT questions directing the user to use asynchronous streams rather than polling for received bytes. This seems to be a red herring; if you feel that the threading model is causing a probelm in this case, please clearly describe why switching to async would resolve this issue.
I would like to pre-emptively address reasons that this question may be closed:
This is not a duplicate. There are other questions on SO about BT connections dropping (i.e. Real-time Bluetooth SPP data streaming on Android only works for 5 seconds) but this is not the same issue. I have already added a keep-alive outgoing char transmitted every 1s, and my issue remains.
I'm not asking about an issue specific to my application; at least one other user on SO has encountered this problem.
I've reviewed the Android Bluetooth documentation in detail, and I can't see any obvious reason for this to happen.
I'm not asking for an opinion; I'm asking for an objective answer as to why the bytes stop being received.
Ok, I have a partial answer for this one. First, a bit more background:
I was running the BT stream polling on a thread which executed a runnable every 2s
The buffer being used to read the stream was 1024 elements long
I had a suspicious that this might be some background buffer running out of space. So, I changed the 2s to 500ms and the 1024-length to 10024. Now, I've had about 20 minutes of connectivity without any trouble (and still going).
It would be nice to find the smoking gun for this. I initially thought that stream.Available() would be sufficient to tell if a buffer was getting filled up, but in this scenario, stream.Available() is actually returning 0 when the Android device stops receiving. So I'm not really sure which queue to check to prove that this issue is related to a buffer becoming filled.

Which is better between an android app and a server? Socket or timer?

I'm going to make an android app that needs to work like an instant messaging (Chat) application, but a little different. It needs to send and receive some short messages, and it's important that it delivers the messages from a web server to the android client quickly (that's a synchronizing app).
Also, the internet connection may be unstable (like GPRS). The server application uses .net 4.5 (may be a windows service or web service)
I've searched around but the answers were not clear for my questions. My questions are as follows:
Is it better to use an open socket or check the server every few seconds? (max allowed delay is 15-20 seconds)
How much network traffic does a socket use in a day, if it is open and no message passes?
How many sockets can be open at the same time?
It really depends on what you want to do, but here are some answers :
Reopening a TCP connection every few seconds probably won't hurt. Close+reopen is how most HTTP connections work.
An idle TCP socket doesn't send any traffic at all, unless you enable TCP keepalive, but even then it is still very light (and often adjustable).
Usually a lot, but is really depends on your software and hardware. A desktop computer may have 1000 open connections on normal load (but can certainly handle more). A big server may handle millions open connections.
Depending on what your 'synchronizing' thing is, you should consider synchronizing with GPS time. It is present on most mobile devices and have a precision around nanoseconds (= all devices will have the same GPS time, give or take some ns). But then the server may need GPS time too, depending on what you do.
Also depending on your application, you should consider using UDP sockets. The good points are that you only need one UDP server socket to handle ALL the UDP clients (you can't do lighter), and that it is more reliable time-wise (when there is a problem, TCP may re-transmit with high delay, while UDP is all or nothing, = you handle up-to-date re-transmit yourself). The downsides are that it is unreliable (messages can be dropped or corrupted, therefore you may want to add some safety), and that some ISP may restrict UDP more than TCP (test yourself to be sure, but usually there is no problems). Note that with UDP, you may need to 'keep alive' yourself, by sending a dummy message, but it is only needed if the 'connection' is idle for too long.

How to recover bluetooth packet loss?? Android

I'm currently creating an Android App where it collects data through bluetooth and draw a real time graph but it seems like after short while there is packet loss and graph comes out weird. I've been searching for a while how to recover the loss but seems like there is no way.... only TCP/IP or UDP has.... Since I need all the data, I can't ignore the packets that doesn't have starting bit or end bit. Is there anyway to prevent the loss or recover the loss completely?
Thanks
Use of RFComm on Android already has built in packet order and reliability like TCP. You should try running tests to see if the Android device is too far away, receiving accurate information, has a bad Bluetooth module, or if the sensor is at fault.

Android: slow network during phone calls

We're working on an app that streams a large amount of data out via UDP for GSM-based phones. The idea is to use it while in conjunction with a voice call. If no voice call is present, things are good. However, if a voice call is active, it seems that most of the data we're sending out simply never makes it, even on HSPA+. If we enable Wifi, then everything is good.
I'm worried that this is a physics problem, rather than a phone one. I ruled out CPU contention by inserting a log statement after we send a chunk of data, and saw that it appeared plenty of times.
Is the 3G radio capable of sending data and voice simultaneously well? We tried a speed test during a voice call and saw a huge drop in bandwidth.
I've run into exactly this problem on AT&T's network in the US. They simply throttle the bandwidth while the call is in progress; whether you're on 3G or H. To see how much you're getting throttled try installing speedtest.net's app and running a speed test during and outside a call.
In the bay area I see data rates as low as 30kbit/s during a call on AT&T's network. On T-Mobile it's not throttled so much (same location). A partner in Israel tried the same test and saw only slight throttling during a call -- he was still seeing 500+kbit/s using the same phone that we tested on in the US. (The same phone that got several Mbit/s outside a call in the US.)
As the poster above points out, CDMA phones can't use data concurrently with a phone call at all (but you said GSM explicitly in your post anyway).
Yes, when you are in a call, there might be not internet connection at all. It depends on the type of network you are in. It would vary from GSM, CDMA, and also the connection type, ie. GPRS, EDGE, 3G or 4G. The 3G and upcoming 4G connections should be able to simultaneous give you network connectivity and voice calling.
Yes, the radio is capable of sending both voice and data simultaneously, but from what I understand its a limitation of the network that your phone uses. If you are on Verizon's 3g network than this is probably your problem. Below is an article that goes into some details about the differences between at&t and Verizon's networks: http://mashable.com/2011/01/11/cdma-umts-att-verizon-networks/
I don't know if this case apply to the operator you are using, but for the operators in my country, they limit the bandwidth used per phone, so if the user use calls and internet connection in the same time, you must subtract the bandwidth used for the phone call, which as i know 48 Kb/s for GSM networks(as maximum) and some of operators limits the call bandwidth for 24 Kb/s and and the total available bandwidth is 64 Kb, so the rest of the bandwidth is used for internet, and i don't know the bandwidth user for 3G networks.
BTW, some phones doesn't support phone calls and internet usage in the same time
all the information above belong to personal information able to be wrong
I do confirm the bandwith is reduced during phone calls unless you are using wifi.
This seems to come from the system, not from the operator. This because it is reported with any hardware / any operator / any country. I have searched for some official documentation regarding that but couldn't find any.
I don't think there is any way to work around that so far.

Categories

Resources