qwertvany
@qwertvany
Программист

UDP Socket в Android. Что выбрать NIO или IO? И как в этом разобраться?

Здравствуйте!

Не нашел толковых ответов на эту тему.

На данный момент для взаимодействия с "железякой" используются сокеты. Я создаю сокет(DatagramSocket) на одном мне нужном порту(можно выбирать и случайный), все дальнейшие операции должны производиться именно с этого порта. Таймаут выставлен в 1 секунду. Во все остальные части(другие потоки) я передаю именно этот созданный экземпляр сокета.

Взаимодействую с ними следующими образами:

  1. 1. Периодический опрос(раз в 4 секунды) - этого требует устройство иначе оно выходит из режима "захвата". Использую встроенный механизм Android - Timer;
  2. 2. Когда нужно получить какие-то данные с устройства или передать на него я создаю Thread, с помощью него отправляю запрос и получаю ответ. После того как работа законченна, тред останавливается(не зацикливаю);
  3. 3. Поток который должен крутится постоянно и воспринимать только нужные пакеты данных, остальные игнорировать. Его запускаю и он просто должен крутится(В нем то и вся проблема, до этого обходился без него).


Проблема следующая: при введение пункта 3, приложение перестает работать, как-будто сокет постоянно занят. Пример кода(класс из вышеупомянутого пункта 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:
Разбираясь с этим вопросом, пришел к тому, что мне нужны неблокирующие сокеты.

Испробовал различные примеры - не удалось ничего из них запустить. Получаю либо ничего, либо 0.

В соответствии с тем, что я хочу сделать из предыдущего вопроса у меня появилось два варианта:

Организовать все на блокирующих сокетах(столкнулся с определенными проблемами: скорость отклика, периодически пропадают запросы, в будущем возможна работа с видеопотоком)
Разобраться в неблокирующих сокетах

Чтобы не быть голословным создал репозиторий на гитхабе, где выложил все мои попытки.

Задача стоит следующая, надо сделать одним из способов взаимодействие с устройством по сети:
1. Держать один поток в программе и в нем организовать очередь запросов. Постоянно крутить цикл в потоке, проверяя есть ли что послать и посылать. После посылок будет идти блок где мы считываем не пришло ли что либо.
2. Можно сделать один поток который будет постоянно вертеть цикл и в нем прослушивать, не пришло ли что, а в отдельных потоках посылать запросы.

На блокирующих сокетах не удалось написать ни одного рабочего примера в одном потоке, только раздельно. В итоге получалась конкуренцая за сокет.
На неблокирущих не удалось получить даже примитивного запрос/ответ( я выясняю в чем дело)
  • Вопрос задан
  • 1774 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы