I have a native C application on an Android 4.3 device which transmits and receives data via UDP.
I noticed that the device is sending out ARP messages every 30-45 seconds while data are being actively transmitted/received via UDP to/from a remote IP address.
I would expect that as long as data are being exchanged actively there wouldn't be a need for sending out ARP messages as a cache is maintained. However, that doesn't seem to be the case.
Is this default and expected behavior on Android ?
Is there some configurable option when creating a socket which controls the frequency of these ARP messages?
Related
👋
I'm researching for a PoC that users would have a mobile app (Android and iOS) connected to a Bluetooth device. Users would lock their cellphone, put them away (close enough for keeping the Bluetooth connection) then the mobile app would stream (broadcast the Bluetooth packets) to an HTTP endpoint.
The mobile app would behave like a hub broadcasting Bluetooth packets.
The stream should last for about 1 - 2 hours.
Would that work or Android and iOS eventually terminate the app?
On iOS, it seems like if you enable Bluetooth-LE related background modes [1], you should be able to "handle important central role events, such as when a connection is established or torn down, when a peripheral sends updated characteristic values, and when a central manager’s state changes.". The caveat to this is that once woken up, you only have a short amount of time (approximately 10 seconds) to perform some processing like sending an HTTP request.
[1] https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html
As shown above, I have a socket server (in UDP) running on my Raspberry Pi. I also have a socket client running on my Android app.
Currently, the app client always initiates communication and the RasPi always responds.
The RasPi can even initiate communication and send socket packet to anyone if it knows the IP address.
The problem is my app has to wait for a Thread to receive data forever (basically polling). Like below:
uniSocket.receive(receivePacket);
Should both RasPi and Android run clients and servers or is there something like Datagram_Socket_Callback or some asynchronous method to receive and send data.
The receive call will block until there is something to receive. That isn't polling; it's just waiting. It could wait in the receive call for days at a time if there's no notification to be sent. And that occupies no more resources than a server threading running on the android side (waiting for a connection) would occupy.
You probably will need some kind of periodic keep-alive to ensure the other side hasn't disappeared. You can do that yourself at the application layer, or TCP provides a keep-alive mechanism you can activate with setsockopt for this purpose.
In other words, create a socket, enable TCP keep-alives, send an "I'm waiting for notifications" message to the server, and then call receive to wait. The server then maintains a list of client connections waiting for notifications, and can then send data through a connection whenever there is something to be sent.
For your normal client-server communications, you could use the same socket, but it might be more complicated to synchronize that way, so alternatively, you could just create another socket in parallel.
I don't know a lot about android/app development but obviously your client will need to be prepared to re-create the connection if it's broken. I can think of many reasons why that might happen in normal usage. For example, the initial connection might be created from an IP address obtained on your home network. Then you walk out of your house and lose that IP address. You may now need to recreate the connection with a different IP address on the cell network (or the wifi at the coffee shop or whatever). If the phone goes into Airplane mode, you might lose all IP addresses for a time.
I'm sure it's possible to create a server that runs in android as well, but then you have the problem of the RPi needing to know the android's IP address which may change frequently. I would say it's better to keep the client role on the android side.
I'm developing an app to receive data from C++ program every second. The app also need to send data to C++ program sometimes.
Is it suitable to use socket as communication between both instances?
For each instance, does it have to run socket server and client at the same time?
I think there would be different ways of accomplishing this depending on required timing behavior (does the device have to receive messages synchronously, should messages that cannot be delivered in time be cached till they can be delivered, etc.), public reachability of the android device (if they are connected over mobile networks they are behind NAT in many mobile networks) and if the devices could go into standby mode or not.
Using stream sockets (TCP) if the mobile device stays awake the whole time or processing has to happen always synchronously.
In this case one end would have to be the "server" and one end to be the "client". Because mobile devices tend to go into standby mode i'd use the C++ program (if it runs on a non-mobile device) to be the server - this would be the end that creates a socket, binds it and then uses listen to wait for incoming connections. Whenever the client connects to the server it has to accept the connection which then can be used bidirectionally by using the same handle for send and receive.
The mobile device then would create a socket and connect to the server and could transmit data to it (it does not have to bind or listen). Over the same connection the device could receive data from the server.
If the server is required to send data to the mobile device even when the mobile device has not established a connection and the mobile device is able to go into standby mode one could either periodically wake the device and poll the server or use the firebase cloud messaging system or even short message service or - if the device is not able to go into standby mode - simply create a listening socket too that accepts incoming connections from the C++ application.
Using datagram sockets (UDP)
In this case both the C++ application and the Android application would create and bind a socket to a specific port. Then they can both simply send packets (unreliable) to other clients or even multicast them in a local area network by sending them a multicast address. Of course the mobile device would miss packets that have been sent from the C++ application during periods where it's in standby mode and the C++ application would miss packets during times it's not running.
Using a message queue (if the mobile device may go to standby mode and has to receive messages asynchronously)
In this case both programs would not have to run at the same time if the queues are persistent, but a message broker would have to (for example RabbitMQ). The C++ application could simply push messages into the queue and any subscribed mobile device would receive them either immediately or (for persistent queues) later whenever the devices connects to the server.
Messaging from the mobile device to the server could also be realized over a message queue if synchronous behavior is not required or over a traditional webservice or even a socket.
Hi I am developing android application in which I want show whether other person is online or not so that person can intiate the communication.I thought about few solution :
1) Implementing heartbeat mechanism, in which device will send ping request to server after fix interval of time.
2) Server will send push type ping to client and client will give response on that so that server will know that client is online.
First case causes battery and data issue, while second one causes delay in push which will affect the process.
Is there any better solution for this problem? Apart from these or improvise version of above one.
nilkash. Virtually any method for checking network connectivity will at the end result in sending periodical pings between device and the server. Even push type ping will actually do the same (but it saves battery because push notifications aggregate messages for all applications in-to a single connection to a google server). So the best solution is just a proper combination of optimizations and you have to choose them depending on your requests.
Server pushes are power efficient, mostly because they reuse the
same connection for all applications, but the delay can be huge,
something like 10 minutes.
You can subscribe to connectivity
events and send "online" message to server once you are online. (But
not once you are offline because you are... offline). This will give
you immediate online events.
Do not send pings from device when there is no connectivity. Your application should be absolutely idle so as not to use battery.
There is no easy way to find out
when client goes offline on server side. You have to trade
traffic/battery for time resolution. More often you send pings, the
better resolution is. But you can't change ping interval for pushes,
so if you need better resolution, then you need to use your own
connection. But you can send other useful data through that connection too.
If you keep a TCP connection, then your pings can be
very data efficient: TCP keep alive packets are just 60/54 bytes.
But then you have to keep open connections with all clients on the
server. This may be a problem if you have a lot of clients.
The best combination may be something like that: you always send online message from a client when it becomes online. You keep TCP connection while the application is in foreground. You use the same connection to transfer data to and from the application. When your application goes to background you fallback to power consuming push based pings and do them at 10 minutes basis.
An embedded device will send data through BLE. I developed an Android application to receive data, but have the following problem:
When the device connects to mobile BLEit will send data immediately but I am not able to read data, if I give a delay the app starts reading characteristics but will not be collecting data.
So when device BLE connects to mobile BLE how many milliseconds will it take to show the services? So I can match delay and receive data.
Instead of manually setting delays, you can use onConnectionStateChange, and onServicesDiscovered callbacks to execute your code based on the connection stage.