I have an 802.3 wired transmitter application on my computer that I've written to broadcast UDP packets every 10ms. Each broadcast packet contains a 4-byte integer value that is unique to its particular packet, which allows me to figure out on the receiver end exactly how many packets have been dropped.
I have verified that the transmitter works with Wireshark. I set up four 802.11 receivers (2 android phones and 2 laptop computers) on the same network. The laptops received 95% of the UDP broadcast packets; one phone received 89%; the other phone received 40%.
Why?
Here is part of my android receiver code:
public class NetThread extends Thread {
int[] pkt_nums;
int p;
NetThread(int[] pkt_nums)
{
this.pkt_nums = pkt_nums;
for (int i=0; i<pkt_nums.length; i++)
{
pkt_nums[i]=0;
}
p = 0;
}
@Override
public void run()
{
receiveData();
}
public void receiveData()
{
// request permission to do network operations in manifest file...done
// start the network side of things
DatagramSocket sock = null;
DatagramPacket pkt = null;
try
{
byte[] data = new byte[C.PAYLOAD_MAX];
sock = new DatagramSocket(C.NET_PORT);
sock.setSoTimeout(C.NET_SO_TIMEOUT);
pkt = new DatagramPacket(data, 0, C.PAYLOAD_MAX);
while (true)
{
Thread.sleep(0); // allow for an interrupt
try
{
sock.receive(pkt);
int length = pkt.getLength();
boolean success = writeToBuffer(pkt.getData(), length);
if (!success) break;
}
catch (InterruptedIOException e)
{
// thrown when a timeout occurs
Log.d(C.DTAG, "net: no packets yet");
}
}
Log.d(C.DTAG, "buffer is full. done receiving.");
if (sock != null) sock.close();
}
catch (InterruptedException x)
{
Log.d(C.DTAG, "net: was interrupted.");
}
catch (SocketException e)
{
Log.d(C.DTAG, "net: SocketException");
e.printStackTrace();
}
catch (IOException e)
{
Log.d(C.DTAG, "net: IOException");
e.printStackTrace();
}
if (sock != null) sock.close();
}
public boolean writeToBuffer(byte[] data, int length)
{
// each packet should have exactly 4 bytes - a number
int pkt_num = data[0] & 0x000000FF | data[1]<<8 & 0x0000FF00 | data[2]<<16 & 0x00FF0000 | data[3]<<24 & 0xFF000000;
if (p < pkt_nums.length)
{
pkt_nums[p++] = pkt_num;
return true; // success
}
else
{
return false;
}
}
}
I declare the above class in my main activity as follows:
mNetThrd = new NetThread(pkt_nums);
mNetThrd.setDaemon(true);
mNetThrd.start();
I will try boosting the thread priority now, but I have a feeling I'm doing something wrong. I need to get at least 95% of UDP broadcast packets for my application.
More details: Laptops and phones are situated next to each other, 30 ft from the router with line-of sight visibility. Laptop 1 received 95% of packets. Laptop 2 received 94%. Phone 1 received 89%. Phone 2 received 40%. Both ran the same app. Other network traffic is minimal. Dropped packets in android typically happen in groups of 20-50 at a time. 802.11 has a clean channel. Each packet contains a 4-byte payload.
Is there something drastically wrong with my receiver code or is this another issue altogether?