java.io.IOException: 读取失败,套接字可能关闭或超时,读取 ret: -1

时间:2021-05-01 10:34:02

标签: java android bluetooth

我在 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 尝试了所有解决方案。请帮忙。

0 个答案:

没有答案
相关问题