For receiving UDP broadcast packets from the server to an android device, i used a service class and listen for packets in a thread. It receives the packet successfully. The
I suppose that you are capturing only a single packet by saying
socket.receive(packet);
This is a Blocking I/O call which will wait infinitely until it receives a packet so once first packet arrives it is done waiting and next command executes i.e
messQueue.add(packet);
However when multiple packets are been received you need to continue receiving packets. in your case you just stopped receiving packages after arrival of first package
Note: UDP being a un-reliable protocol doesn't guarantee packet delivery so there might be a case a packet is lost , However this can't be a problem on every run of your program , However a nice way to check whether the packet is hitting your machine and problem is within your application (application is not able to handle the packets recieved) use tcpdump (it's a command-line utility for linux-based OS or MAC) use the following command
sudo tcpdump -i <interface name(one that handles traffic) eth0, eth1 .. en0, en1 (for MAC)> host <ipaddress or hostname of UDP Broadcast server>
Example:
sudo tcpdump -i en1 host 187.156.13.5
(if tcpdump command not found then go forward and install it)
By using this command you will see packets pumping in from destination ump server on terminal if you see more then one packets arriving then you would be sure that packets are arriving at machine , However application falls short to address the packet
it might help
I think your problem is mainly that you use Udp Broadcast over wifi.
Their are two very well documented answers why this is a very slow way to operate and why there are much more packet losts:
answer number one.
answer number two.
The thing I did to solve the extremely slow bandwidth was some kind of multi-unicast protocol:
This is the code in java:
DatagramPacket packet = new DatagramPacket(buffer, size);
packet.setPort(PORT);
for (byte[] clientAddress : ClientsAddressList) {
packet.setAddress(InetAddress.getByAddress(clientAddress));
transceiverSocket.send(packet);
}
If you receive multiple datagrams in a short burst, your receiver loop may have trouble keeping up, and the OS-level RCVBUF in the socket may overflow (causing the OS to drop a packet it indeed did receive).
You might get better handling of short bursts if you increase the RCVBUF size. Prior to doing this, get an idea of how big it is already via socket.getReceiveBufferSize. Also bear in mind that the number of bytes in the receive buffer must accommodate not just the payload but also the headers and the sk_buff structure that stores packets in the kernel (see, e.g. lxr.free-electrons.com/source/include/linux/…).
You can adjust the recieve buffer size via socket.setReceiveBufferSize - but bear in mind that this message is just a hint, and may be overridden by settings in the kernel (if you request a size bigger than the max size allowable by the current kernel network settings, then you'll only get the max size).
After requesting a bigger receive buffer, you should double check what the kernel has allowed by calling socket.getReceiveBufferSize.
If you have the right permissions, you should be able to tweak the max buffer size the kernel will allow - see e.g. https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Web_Platform/5/html/Administration_And_Configuration_Guide/jgroups-perf-udpbuffer.html
[ Note that, in general, this will accommodate for short bursts where datagrams arrive faster than your client loop can read them - but if the client loop is chronically slower than datagram delivery, you'll still get occasional drops due to overflow. In this case, you need to speed up your client loop, or slow down the sender.
Also, as otherwise noted in other answers, packets may actually be dropped by your network - and mobile networks especially may be prone to this - so if you absolutely need guaranteed delivery you should use TCP. However, if this were your primary problem, you would expect to see dropped packets even when your server sends them slowly, rather than in a burst.]
The problem with UDP is that your sender (your server) does not know you (your android device) missed some. It's not lost because you can't read it fast enough, sometimes just over the air interference/congestion or a busy socket.
The receiver would only know if:
Once the packet is lost, it's lost. You got two options:
(option 1: all this resend requesting is just pseudo-TCP, so you might just consider abandoning UDP and go TCP)
With reference to above explanation by me following changes you can make to make code behave according to requirement
I suppose you can make following changes to make your problem code work instead of creating socket into listenAndWaitAndThrowIntent(InetAddress broadcastIP, Integer port ) method create it in startListenForUdpBroadcast() as follows
socket = new DatagramSocket(port, broadcastIP);
socket.setBroadcast(true);
while (shouldRestartSocketListen) {
listenAndWaitAndThrowIntent(broadcastIP, port, socket);
}
Now you also need to change implementation of listenAndWaitAndThrowIntent method as follows
private void listenAndWaitAndThrowIntent(InetAddress broadcastIP,
Integer port, DatagramSocket socket) throws Exception {
byte[] recvBuf = new byte[64000];
//socket.setSoTimeout(1000);
//change value of condition in for loop to desired number of packets you would like to receive in below example it is 2 so it captures two packets
for (int i=0 ; i <= 2 ; i++ ){
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
socket.receive(packet);
messQueue.add(packet);
}
}
Try this it should work !! it might help