I am measuring the data rate of the network traffic on an Android device both actively, by downloading multiple files concurrently and measuring the loaded bytes, and passively by using a locally implemented vpn service. The active measurement works well when the vpn service is deactivated. When activating the vpn service measures approximately the same data rate as the active tool, but after some while (~5mins) both data rates drop to zero. I also get sockettimeoutexception in the active tool but am not sure if this is the reason for the malfunction.
Here is the runnable used for the local VPN:
private static class VPNRunnable implements Runnable
{
private final String TAG = VPNRunnable.class.getSimpleName();
private FileDescriptor vpnFileDescriptor;
private ConcurrentLinkedQueue<Packet> deviceToNetworkUDPQueue;
private ConcurrentLinkedQueue<Packet> deviceToNetworkTCPQueue;
private ConcurrentLinkedQueue<ByteBuffer> networkToDeviceQueue;
public VPNRunnable(FileDescriptor vpnFileDescriptor,
ConcurrentLinkedQueue<Packet> deviceToNetworkUDPQueue,
ConcurrentLinkedQueue<Packet> deviceToNetworkTCPQueue,
ConcurrentLinkedQueue<ByteBuffer> networkToDeviceQueue)
{
this.vpnFileDescriptor = vpnFileDescriptor;
this.deviceToNetworkUDPQueue = deviceToNetworkUDPQueue;
this.deviceToNetworkTCPQueue = deviceToNetworkTCPQueue;
this.networkToDeviceQueue = networkToDeviceQueue;
}
@Override
public void run()
{
Log.i(TAG, "Started");
FileChannel vpnInput = new FileInputStream(vpnFileDescriptor).getChannel();
FileChannel vpnOutput = new FileOutputStream(vpnFileDescriptor).getChannel();
try
{
ByteBuffer bufferToNetwork = null;
boolean dataSent = true;
boolean dataReceived;
while (true)
{
if (!VPN) {
Thread.currentThread().interrupt();
}
if (dataSent)
bufferToNetwork = ByteBufferPool.acquire();
else
bufferToNetwork.clear();
// TODO: Block when not connected
int packetSize = vpnInput.read(bufferToNetwork);
if (packetSize > 0)
{
dataSent = true;
bufferToNetwork.flip();
Packet packet = new Packet(bufferToNetwork);
if (packet.isUDP())
{
deviceToNetworkUDPQueue.offer(packet);
}
else if (packet.isTCP())
{
deviceToNetworkTCPQueue.offer(packet);
}
else
{
Log.w(TAG, "Unknown packet type");
Log.w(TAG, packet.ip4Header.toString());
dataSent = false;
}
totalBitsSent += packetSize*8; // Update total bits received including headers and payload
}
else
{
dataSent = false;
}
ByteBuffer bufferFromNetwork = networkToDeviceQueue.poll();
if (bufferFromNetwork != null) {
bufferFromNetwork.flip();
packetSize = bufferFromNetwork.remaining(); // Calculate the total size of the received packet
while (bufferFromNetwork.hasRemaining()) {
vpnOutput.write(bufferFromNetwork);
}
dataReceived = true;
totalBitsReceived += packetSize*8; // Update total bits received including headers and payload
ByteBufferPool.release(bufferFromNetwork);
}
else
{
dataReceived = false;
}
// TODO: Sleep-looping is not very battery-friendly, consider blocking instead
// Confirm if throughput with ConcurrentQueue is really higher compared to BlockingQueue
if (!dataSent && !dataReceived)
Thread.sleep(10);
}
}
catch (InterruptedException e)
{
Log.i(TAG, "Stopping");
try {
closeResources(vpnInput, vpnOutput);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} catch (SocketTimeoutException e) {
Log.i(TAG, "ERROR: " + e);
} catch (IOException e)
{
Log.w(TAG, e.toString(), e);
}
}
//processPacket(
}
Does someone have a idea what could cause this behaviour? The target is to measure the data rate both actively and passively without performance drop. Help is very much appreciated!
- earl