I
I
Ivan Shalimov2017-08-08 17:22:48
Android
Ivan Shalimov, 2017-08-08 17:22:48

UDP socket in android. What to choose NIO or IO? And how to figure it out?

Hello!

Didn't find any good answers on this topic.

At the moment, sockets are used to interact with the hardware. I create a socket (DatagramSocket) on one port I need (you can choose a random one), all further operations must be performed from this port. The timeout is set to 1 second. In all other parts (other threads) I pass exactly this created socket instance.

I interact with them in the following ways:

  1. 1. Periodic polling (every 4 seconds) - this is required by the device, otherwise it exits the "capture" mode. I use the built-in mechanism of Android - Timer;
  2. 2. When I need to get some data from the device or transfer it to it, I create a Thread, use it to send a request and get a response. After the work is completed, the thread stops (do not loop);
  3. 3. A stream that must spin constantly and receive only the necessary data packets, and ignore the rest. I launch it and it just has to spin (That's the whole problem in it, before that I did without it).


The problem is the following: when point 3 is entered, the application stops working, as if the socket is constantly busy. Code example (class from above point 3):

import android.os.Handler
    import android.os.Message
    import com.controller.labaratory.controller.App
    import com.controller.labaratory.controller.models.Container
    import java.net.*
    
    /**
     * Created by ivan on 03/08/17.
     */
    class DataPacketThread(val handler: Handler,
                           val socket: DatagramSocket,
                           val addres: InetAddress):Thread() {
    
    
        override fun run() {
            super.run()
            while (!socket.isClosed){
                try{
                    //socket.soTimeout=0
                    var buffer:ByteArray = kotlin.ByteArray(1024)
                    val packet = DatagramPacket(buffer, buffer.size)
    
                    socket?.receive(packet)
    
                    val odin:Byte = -1
    
                    if (!(buffer[0] == odin)){
                        if(packet.data[0].toInt() == 4){
                            val responseByteArray:ByteArray = byteArrayOf(1,33,
                                    packet.data[2],packet.data[3])
    
                            val packetResponseAnswer = DatagramPacket(responseByteArray,
                                    responseByteArray.size, addres, 1026)
                            socket?.send(packetResponseAnswer)
    
                            handler?.sendMessage(
                                    Message.obtain(
                                            handler,
                                            App.UdpClientHandler.DATA_PACKET_RECEIVE,
                                            HandlerContainer(825, Container(
                                                    packet.length,
                                                    packet.data))))
                        }
    
                    }
                } catch (e:SocketTimeoutException){
                    e.printStackTrace()
                } catch (e:SocketException){
                    e.printStackTrace()
                }
    
            }
        }
    
        fun end(){
            socket.close()
        }
    }


UPD:
Dealing with this issue, I came to the conclusion that I need non-blocking sockets.

Tried various examples - none of them could run. I get either nothing or 0.

In accordance with what I want to do from the previous question, I have two options:

Organize everything on blocking sockets (I encountered certain problems: response speed, requests periodically disappear, work with a video stream is possible in the future)
Understand non-blocking sockets

In order not to be unfounded, I created a repository on github, where I posted all my attempts .

The task is the following, it is necessary to make one of the ways to interact with the device over the network:
1. Keep one thread in the program and organize a queue of requests in it. Constantly spin the loop in the stream, checking whether there is something to send and send. After the parcels, there will be a block where we read whether something has arrived.
2. You can make one thread that will constantly spin the cycle and listen in it if something has come, and send requests in separate threads.

On blocking sockets, it was not possible to write a single working example in one thread, only separately. As a result, it turned out competing for the socket.
On non-blocking, it was not possible to get even a primitive request / response (I find out what's wrong)

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question