Можно ли использовать один и тот же сокет UDP для отправки и получения в разных потоках? - PullRequest
0 голосов
/ 16 июня 2019

Я работаю над программой Android, которая отправляет некоторые данные на сервер и получает другие данные с этого сервера.Я пытаюсь реализовать этапы отправки и получения в двух разных потоках, но это не работает, поток с командой send работает хорошо, и данные достигают сервера, но поток приема блокируется командой приема, потому чтоон не может получить данные, которые сервер отправляет обратно.

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

Это код, который работает:


    private Button startButton;

    AudioRecord recorder;

    private int sampleRate = 16000 ;
    private int port=50005;
    private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
    private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
    private boolean status = true;
    DatagramPacket packet;
    private String ipADD = "34.243.123.14";
    DatagramSocket socket;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        r = new PipedInputStream();
        w = new PipedOutputStream();

        try {
            w.connect(r);
            socket = new DatagramSocket();
            socket.setSoTimeout(5000);
        } catch (IOException e) {
            e.printStackTrace();
        }

        startButton = findViewById (R.id.start_button);

        startButton.setOnTouchListener(touchListener);

    }

    private final OnTouchListener touchListener = new OnTouchListener() {

        @Override
        public boolean onTouch(View arg0, MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_DOWN){
                Log.d("VS","Button pressed");
                status = true;
                startStreaming();
                receiverThread = new Thread(new receiver());
                receiverThread.run();
            }
            if(event.getAction() == MotionEvent.ACTION_UP){
                Log.d("VS","Button released");
                status = false;
            }
            return true;
        }

    };


    public void startStreaming() {

        Thread streamThread = new Thread(new Runnable() {

            @Override
            public void run() {
                try {

                    DatagramSocket socket = new DatagramSocket(33033);

                    Log.d("VS", "SENDER Socket Created in port:"+socket.getLocalPort());

                    byte[] buffer = new byte[10000];

                    Log.d("VS","Buffer created of size " + minBufSize);


                    final InetAddress destination = InetAddress.getByName(ipADD);

                    ByteArrayOutputStream out = new ByteArrayOutputStream();

                    recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRate,channelConfig,audioFormat,minBufSize*10);
                    Log.d("VS", "Recorder initialized");
                    AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, AudioFormat.CHANNEL_OUT_MONO,
                            AudioFormat.ENCODING_PCM_16BIT, 8000*2, AudioTrack.MODE_STREAM);

                    recorder.startRecording();

                    while(status == true) {


                        //reading data from MIC into buffer
                        Log.d("VS", "Filling buffer...");
                        minBufSize = recorder.read(buffer, 0, buffer.length);
                        Log.d("VS", "Buffer filled");
                        packet = new DatagramPacket (buffer,buffer.length,destination,port);

                        socket.send(packet);
                        socket.receive(packet);

                    }

                } catch(UnknownHostException e) {
                    Log.e("VS", "UnknownHostException");
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.e("VS", "IOException");
                }
            }

        });
        System.out.println("streamThread Started");
        streamThread.start();

    }
}

И этот код, который я пытаюсь сделать, работает:


    private Button startButton;

    AudioRecord recorder;

    private int sampleRate = 16000 ;
    private int port=50005;
    private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
    private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
    private boolean status = true;
    DatagramPacket packet;
    private String ipADD = "34.243.123.14";
    DatagramSocket socket;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        r = new PipedInputStream();
        w = new PipedOutputStream();

        try {
            w.connect(r);
            socket = new DatagramSocket();
            socket.setSoTimeout(5000);
        } catch (IOException e) {
            e.printStackTrace();
        }

        startButton = findViewById (R.id.start_button);

        startButton.setOnTouchListener(touchListener);

    }

    private final OnTouchListener touchListener = new OnTouchListener() {

        @Override
        public boolean onTouch(View arg0, MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_DOWN){
                Log.d("VS","Button pressed");
                status = true;
                startStreaming();
                receiverThread = new Thread(new receiver());
                receiverThread.run();
            }
            if(event.getAction() == MotionEvent.ACTION_UP){
                Log.d("VS","Button released");
                status = false;
            }
            return true;
        }

    };


    public void startStreaming() {

        Thread streamThread = new Thread(new Runnable() {

            @Override
            public void run() {
                try {

                    DatagramSocket socket = new DatagramSocket(33033);

                    Log.d("VS", "SENDER Socket Created in port:"+socket.getLocalPort());

                    byte[] buffer = new byte[10000];

                    Log.d("VS","Buffer created of size " + minBufSize);


                    final InetAddress destination = InetAddress.getByName(ipADD);

                    ByteArrayOutputStream out = new ByteArrayOutputStream();

                    recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRate,channelConfig,audioFormat,minBufSize*10);
                    Log.d("VS", "Recorder initialized");
                    AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, AudioFormat.CHANNEL_OUT_MONO,
                            AudioFormat.ENCODING_PCM_16BIT, 8000*2, AudioTrack.MODE_STREAM);

                    recorder.startRecording();

                    while(status == true) {


                        //reading data from MIC into buffer
                        Log.d("VS", "Filling buffer...");
                        minBufSize = recorder.read(buffer, 0, buffer.length);
                        Log.d("VS", "Buffer filled");
                        packet = new DatagramPacket (buffer,buffer.length,destination,port);

                        socket.send(packet);

                    }

                } catch(UnknownHostException e) {
                    Log.e("VS", "UnknownHostException");
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.e("VS", "IOException");
                }
            }

        });
        System.out.println("streamThread Started");
        streamThread.start();

    }

public class receiver implements Runnable {

        public receiver() {
        }

        public void run() {
            try {
                while (true){
                    byte[] buffer = new byte[3000];
                    System.out.println("Creating packet...");
                    DatagramPacket mypacket = new DatagramPacket(buffer, buffer.length);
                    System.out.println("Waiting for receiving packet...");
                    socket.receive(mypacket);
                }
            }
            catch (Exception e){
                System.out.println(e.getMessage());
            }catch(Error e){
                System.out.println(e.getMessage());
                // Ignore
            }
        }
    }
}

Нет ошибки, просто, поскольку получатель не получает ничего от сокета, он продолжает ждать, пока не истечет время ожидания.

...