java: Как реализовать прием и передачу udp пакетов в разных потоках для параллельной работы?

160
06 ноября 2021, 01:50

пишу приложение для android, при реализации, приведенной ниже, работает прием пакетов, но не работает отправка. если убрать запуск потока для приема сообщений - отправка начинает работать. Как реализовать одновременную прием и передачу udp пакетов в разных потоках?

package com.example.pavel.controldevicelan;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class MainActivity extends AppCompatActivity {
    String serIpAddress;
    int port_trans = 20020;
    int port_rec = 20021;
    DatagramSocket socket_udp_rec;
    DatagramSocket socket_udp_trans;
    InetAddress ipAddress;
    byte[] buf_rec = new byte[2000];
    ImageView imageViewReceive; //лампочка - для определения факта прихода пакета
    boolean onoff = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageViewReceive = (ImageView) findViewById(R.id.imageViewReceive);
        try
        {
            socket_udp_rec = new DatagramSocket(port_rec);
            socket_udp_trans = new DatagramSocket(port_trans);
        } catch (SocketException e) {
            e.printStackTrace();
        }
        ReceivePackThread sender_rec = new ReceivePackThread(); // объект представляющий поток приема сообщений
        sender_rec.execute();//если убрать эту строку, то передача начинает работать
    }
    //отправка сообщений осуществляется по нажатии на кнопку
    public void onClick (View v)
    {
        EditText editText = (EditText)findViewById(R.id.editIPaddress);
        serIpAddress = editText.getText().toString();
        if (serIpAddress.isEmpty()){
            Toast msgToast = Toast.makeText(this, "Введите ip адрес", Toast.LENGTH_SHORT);
            msgToast.show();
            return;
        }
        SenderThread sender = new SenderThread();// объект представляющий поток отправки сообщений
        sender.execute();
    }

    //поток для приема пакетов, запускается в onCreate
    class ReceivePackThread extends AsyncTask<Void, Void, Void>
    {
        @Override
        protected Void doInBackground(Void... params) {
            while(true)
            {
                try {
                    buf_rec = new byte[2000];
                    DatagramPacket packet = new DatagramPacket(buf_rec, buf_rec.length);
                    socket_udp_rec.receive(packet);
                    //если принят любой пакет - меняем цвет лампочки
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (onoff)
                            {
                                imageViewReceive.setImageResource(android.R.drawable.presence_online);
                            }
                            else
                            {
                                imageViewReceive.setImageResource(android.R.drawable.ic_notification_overlay);
                            }
                            onoff = !onoff;
                        }
                    });
                }
                catch (Exception ex)
                {
                    ex.printStackTrace();
                }
            }
            //return null;
        }
    }
    //поток для отправки пакетов, запускается в onClick
    class SenderThread extends AsyncTask<Void, Void, Void>
    {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                ipAddress = InetAddress.getByName(serIpAddress);
                byte[] buf_trans = new byte[4];
                DatagramPacket packet = new DatagramPacket(buf_trans, buf_trans.length,
                       ipAddress, port_trans);
                socket_udp_trans.send(packet);
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
            return null;
        }
    }
}
Answer 1

проблема решена. похоже запуск потоков AsyncTask методом execute() представляет собой последовательное выполнение потоков. для параллельной работы потоков необходимо запускать так - asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); то есть первым запускался поток приема пакетов, выполнялся бесконечно, и ,соответственно, поток отправки пакетов при запуске становился в очередь и бесконечно ждал своего выполнения

READ ALSO
Проблемы в преобразовании данных в Java

Проблемы в преобразовании данных в Java

Начинаю разбираться в Java и у меня проблемы в преобразовании list в массив

113
Динамическая загрузка jar в JVM

Динамическая загрузка jar в JVM

Пытаюсь динамически загрузить файл в JVM при помощи ClassLoader

146
Варианты связи между классами

Варианты связи между классами

Есть например два класса Document и UserУ Document есть поле creator (из числа существующих пользователей)

107
Управление частотой вызова метода

Управление частотой вызова метода

Пишу сервис для обращения к vk apiУ них стоит ограничение на запросы - не более 3 раз в секунду на методы c user token и 20 раз в секунду на методы с group token

192