我在 2-3 天内收到 java.io.IOException: read failed, socket might closed or timeout, read ret: -1
此错误,但无法解决。我在 stackoverflow 上尝试了其他解决方案,但没有奏效。好像问题是在socket.connect();
处产生的,我按照方法操作的时候,发现是库中这段代码抛出的错误:
private int readAll(InputStream is, byte[] b) throws IOException {
int left = b.length;
while (left > 0) {
int ret = is.read(b, b.length - left, left);
if (ret <= 0) {
throw new IOException("read failed, socket might closed or timeout, read ret: "
+ ret);
}
left -= ret;
if (left != 0) {
Log.w(TAG, "readAll() looping, read partial size: " + (b.length - left)
+ ", expect size: " + b.length);
}
}
return b.length;
}
我试了很多次都无法调试。
public void run(){
Log.i("UUID",device.getUuids()[0].getUuid().toString());
Log.i("TAG", "BEGIN mConnectThread");
// Always cancel discovery because it will slow down a connection
bluetoothAdapter.cancelDiscovery();
try{
Log.i("TAG","Connecting to socket...");
socket.connect();
}catch (IOException e){
Log.e("Connect->Run:",e.toString());
// e.printStackTrace();
try{
Log.i("TAG","Trying fallback...");
socket = (BluetoothSocket) device.getClass().getMethod("createRfcommSocket", new Class[]{int.class}).invoke(device,1);
socket.connect();
Log.i("TAG","Connected");
}catch (IOException | NoSuchMethodException | IllegalAccessException | InvocationTargetException er){
Log.i("TAG","Cannot connect");
try{
socket.close();
} catch (IOException ex) {
Log.e("Connect->Close:",er.toString());
ex.printStackTrace();
}
connectionFailed();
return;
}
}
ChatUtils.this.start();
synchronized ( ChatUtils.this){
connectThread = null;
}
connected(device);
}
这是我试图连接到套接字的地方。 以下是我的整个文件:
package com.example.robomonkee_bt;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.os.Handler;
import android.content.Context;
import android.os.Message;
import android.util.Log;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.UUID;
public class ChatUtils {
private Context context;
private final Handler handler;
private BluetoothAdapter bluetoothAdapter;
private ConnectThread connectThread;
private AcceptThred acceptThred;
private final String APP_NAME = "RoboMonkee-bt";
private final UUID APP_UUID = UUID.fromString("0000110a-0000-1000-8000-00805f9b34fb");
public static final int STATE_NONE = 0;
public static final int STATE_LISTEN = 1;
public static final int STATE_CONNECTING = 2;
public static final int STATE_CONNECTED = 3;
public int state;
public ChatUtils(Context context, Handler handler){
this.context = context;
this.handler = handler;
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
state = STATE_NONE;
}
public int getState() {
return state;
}
public synchronized void setState(int state) {
this.state = state;
handler.obtainMessage(MainActivity.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
private synchronized void start(){
if(connectThread != null){
connectThread.cancel();
connectThread = null;
}
if(acceptThred == null){
acceptThred = new AcceptThred();
acceptThred.start();
}
setState(STATE_LISTEN);
}
public synchronized void stop(){
if(connectThread!= null){
connectThread.cancel();
connectThread = null;
}
if(acceptThred != null){
acceptThred.cancel();
acceptThred = null;
}
setState(STATE_NONE);
}
public void connect(BluetoothDevice device){
if(state == STATE_CONNECTING){
if (connectThread != null) {
connectThread.cancel();
connectThread = null;
}
}
connectThread = new ConnectThread(device);
connectThread.start();
setState(STATE_CONNECTING);
}
private class AcceptThred extends Thread{
private BluetoothServerSocket serverSocket;
public AcceptThred(){
BluetoothServerSocket tmp = null;
try{
tmp = bluetoothAdapter.listenUsingRfcommWithServiceRecord(APP_NAME, APP_UUID);
}catch(IOException e){
Log.e("Accept->Constructor:",e.toString());
}
serverSocket = tmp;
}
public void run(){
BluetoothSocket socket = null;
while (state != STATE_CONNECTED) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
Log.e("Accept->Run:",e.toString());
}
}
if(socket != null){
switch (state){
case STATE_LISTEN:
case STATE_CONNECTING:
connect(socket.getRemoteDevice());
break;
case STATE_NONE:
case STATE_CONNECTED:
try{
socket.close();
}catch (IOException e){
Log.e("Accept-> Close Socket", e.toString());
}
}
}
}
public void cancel(){
try{
serverSocket.close();
}catch (IOException e){
Log.e("Accpet-> Close Server",e.toString());
}
}
}
private class ConnectThread extends Thread{
private BluetoothSocket socket;
private final BluetoothDevice device;
public ConnectThread(BluetoothDevice device){
this.device = device;
BluetoothSocket tmp = null;
try{
tmp = device.createRfcommSocketToServiceRecord(APP_UUID);
}catch (IOException e){
Log.e("Connect->Constructor:",e.toString());
}
socket = tmp;
}
public void run(){
Log.i("UUID",device.getUuids()[0].getUuid().toString());
Log.i("TAG", "BEGIN mConnectThread");
// Always cancel discovery because it will slow down a connection
bluetoothAdapter.cancelDiscovery();
try{
Log.i("TAG","Connecting to socket...");
socket.connect();
}catch (IOException e){
Log.e("Connect->Run:",e.toString());
// e.printStackTrace();
try{
Log.i("TAG","Trying fallback...");
socket = (BluetoothSocket) device.getClass().getMethod("createRfcommSocket", new Class[]{int.class}).invoke(device,1);
socket.connect();
Log.i("TAG","Connected");
}catch (IOException | NoSuchMethodException | IllegalAccessException | InvocationTargetException er){
Log.i("TAG","Cannot connect");
try{
socket.close();
} catch (IOException ex) {
Log.e("Connect->Close:",er.toString());
ex.printStackTrace();
}
connectionFailed();
return;
}
}
ChatUtils.this.start();
synchronized ( ChatUtils.this){
connectThread = null;
}
connected(device);
}
public void cancel(){
try{
socket.close();
}catch (IOException e){
Log.e("Connect->Close:",e.toString());
}
}
}
private synchronized void connectionFailed(){
Message message = handler.obtainMessage(MainActivity.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(MainActivity.TOAST, "Can't connect to device");
message.setData(bundle);
handler.sendMessage(message);
ChatUtils.this.start();
}
private synchronized void connected(BluetoothDevice device){
if (connectThread!=null){
connectThread.cancel();
connectThread = null;
}
Message message = handler.obtainMessage(MainActivity.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(MainActivity.DEVICE_NAME, device.getName());
message.setData(bundle);
handler.sendMessage(message);
setState(STATE_CONNECTED);
}
}
我从 device.getUuids()[0].getUuid();
获得了 UUID
另外,我想补充一点,当我尝试连接时,它会连接 2-3 秒,然后再次断开连接。我可以在另一台设备上看到它已连接,然后自动断开连接。
我已经在 IOException: read failed, socket might closed - Bluetooth on Android 4.3 尝试了所有解决方案。请帮忙。