可以使用同一UDP套接字在不同线程中发送和接收吗?

时间:2019-06-16 18:17:30

标签: android sockets udp datagram

我正在研究一个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
            }
        }
    }
}

没有错误,因为接收方没有从套接字接收任何内容,它一直等待直到达到超时。

0 个答案:

没有答案