android отправлять сообщения на несколько серверов сокетов udp - PullRequest
0 голосов
/ 14 июля 2020

Я разрабатываю приложение Android, которое управляет многими платами реле (4 реле на плате). Каждая плата имеет IP-адрес и сервер UDP, который прослушивает один и тот же порт (8888). Каждая плата принимает одни и те же команды и отвечает на них. Моя проблема: когда я отправляю команды на одну доску и переключаюсь на другую (нажимая кнопки в пользовательском интерфейсе приложения), команды отправляются, но они продолжают поступать на предыдущую (я знаю это, глядя на ethe rnet LED), а через 10 - 15 секунд начинают доходить до новой платы. Почему это?

Это мой класс для отправки команд:

package com.cvega.scjpolinox.comm;

import android.util.Log;
import android.os.Handler;
import android.widget.EditText;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;

public class PolyEtherSender implements Runnable {
    private DatagramSocket udpSocket;
    private String strCommand;
    private String ip;
    private Handler handler;
    private EditText etStatus;

    public PolyEtherSender(String ip, String command, Handler handler, EditText etStatus){
        this.strCommand = command;
        this.ip = ip;
        this.handler = handler;
        this.etStatus = etStatus;
    }

    @Override
    public void run() {
        try {
            // target board IP
            InetAddress serverAddr = InetAddress.getByName(this.ip);
            byte[] command = strCommand.getBytes();
            // local socket
            this.udpSocket = new DatagramSocket(null);
            this.udpSocket.setReuseAddress(true);
            this.udpSocket.bind(new InetSocketAddress(8881));
            // command sent to board
            DatagramPacket sendPacket = new DatagramPacket(command, command.length, serverAddr, 8888);
            this.udpSocket.send(sendPacket);

            byte[] response = new byte[4];
            // response
            DatagramPacket responsePacket = new DatagramPacket(response, response.length);
            this.udpSocket.receive(responsePacket);
            if (response[0] == 1) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        etStatus.setText("Open");
                    }
                });
            } else {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        etStatus.setText("Close");
                    }
                });
            }
            this.udpSocket.disconnect();
            this.udpSocket.close();
        } catch (SocketException e) {
            Log.e("Poly", "Socket Error:", e);
        } catch (IOException e) {
            Log.e("Poly", "IO Error:", e);
        }
    }
}

Это код кнопок пользовательского интерфейса (кнопки отрисовываются программно, внутри цикла While, зависит от количества плат пользователю необходимо управлять):

            btStart.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String command = "Rele" + valve.getPort() + "ONT" + conf.getDuracionExtraccion();
                    new Thread(new PolyEtherSender(valve.getIp(), command, polyHandler, etStatus)).start();
                }
            });

            btStop.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String command = "Rele" + valve.getPort() + "OFF";
                    new Thread(new PolyEtherSender(valve.getIp(), command, polyHandler, etStatus)).start();
                }
            });
...