我正在研究一个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
}
}
}
}
没有错误,因为接收方没有从套接字接收任何内容,它一直等待直到达到超时。