Я работаю над программой 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
}
}
}
}
Нет ошибки, просто, поскольку получатель не получает ничего от сокета, он продолжает ждать, пока не истечет время ожидания.