接受线程上的 IOException [英] IOException on accept thread

查看:33
本文介绍了接受线程上的 IOException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序的一部分通过蓝牙连接到设备,通常工作正常,但有时无法连接并出现以下错误

One part of my application connects to a device through Bluetooth and normally works fine but occasionally it won't connect and I get the following error

03-11 10:29:20.328: E/BluetoothComService(8059): accept() failed
03-11 10:29:20.328: E/BluetoothComService(8059): java.io.IOException: Operation Canceled
03-11 10:29:20.328: E/BluetoothComService(8059):    at android.bluetooth.BluetoothSocket.acceptNative(Native Method)
03-11 10:29:20.328: E/BluetoothComService(8059):    at android.bluetooth.BluetoothSocket.accept(BluetoothSocket.java:316)
03-11 10:29:20.328: E/BluetoothComService(8059):    at android.bluetooth.BluetoothServerSocket.accept(BluetoothServerSocket.java:105)
03-11 10:29:20.328: E/BluetoothComService(8059):    at android.bluetooth.BluetoothServerSocket.accept(BluetoothServerSocket.java:91)
03-11 10:29:20.328: E/BluetoothComService(8059):    at com.mypackage.name.bluetooth.BluetoothService$AcceptThread.run(BluetoothService.java:298)

这是我得到异常的那一行

This is the line where I get the exception

socket = mmServerSocket.accept();    

这是完整的AcceptThread

And this is the complete AcceptThread

private class AcceptThread extends Thread {
    // The local server socket
    private BluetoothServerSocket mmServerSocket;
    public boolean successInit = false;

    public AcceptThread() {
        closeAllConnections();

        /*
         * if(mmServerSocket != null) { try { mmServerSocket.close(); } catch
         * (IOException e) { e.printStackTrace(); } }
         */
        BluetoothServerSocket tmp = null;

        // Create a new listening server socket
        while (!successInit) {
            try {
                tmp = mAdapter
                        .listenUsingRfcommWithServiceRecord(NAME, MY_UUID);

                successInit = true;
            } catch (Exception e) {

                successInit = false;
            }
        }

        /*
         * try { tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME,
         * MY_UUID); successInit= true; } catch (IOException e) { Log.e(TAG,
         * "listen() failed", e); tmp = null; successInit = false; }
         */
        mmServerSocket = tmp;
    }

    public void run() {
        if (D)
            Log.d(TAG, "BEGIN mAcceptThread" + this);
        setName("AcceptThread");
        BluetoothSocket socket = null;

        // Listen to the server socket if we're not connected
        while (mState != STATE_CONNECTED) {
            try {
                // This is a blocking call and will only return on a
                // successful connection or an exception
                mAdapter.cancelDiscovery();

                socket = mmServerSocket.accept();
            } catch (IOException e) {
                Log.e(TAG, "accept() failed", e);
                Log.e("Error", "This isn't connecting");
                break;
            }

            // If a connection was accepted
            if (socket != null) {
                synchronized (BluetoothService.this) {
                    switch (mState) {
                    case STATE_LISTEN:
                    case STATE_CONNECTING:
                        // Situation normal. Start the connected thread.
                        connected(socket, socket.getRemoteDevice());
                        break;
                    case STATE_NONE:
                    case STATE_CONNECTED:
                        // Either not ready or already connected. Terminate new
                        // socket.
                        try {
                            socket.close();
                        } catch (IOException e) {
                            Log.e(TAG, "Could not close unwanted socket", e);
                        }
                        break;
                    }
                }
            }
        }
        if (D)
            Log.i(TAG, "END mAcceptThread");
    }

    public void cancel() {
        if (D)
            Log.d(TAG, "cancel " + this);
        try {
            mmServerSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "close() of server failed", e);
        }
    }
}     

这是我在AcceptThread开头调用的函数,希望关闭一切重新启动它

Here is the function I call at the beginning of AcceptThread in hopes to close everything to restart it

public void closeAllConnections() {
    if (mmInStream != null) {
        try {mmInStream.close();}
        catch  (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
    }
    if (mmOutStream != null) {
        try {mmOutStream.close();}
        catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
    }
    if (mmSocket != null) {
        try {
            mmSocket.close();
            //mmSocket.connect();
        }
        catch (IOException e) {
            Log.e(TAG, "close() of connect socket failed", e);
        }
    }
}

我已经通读了 蓝牙文档 和 SO 问题,但我还没有找到任何对我有用的东西,它让我有点困惑,因为这是我第一次通过 BT 连接.

I've read through the Bluetooth Docs and SO questions but I haven't found anything that works for me and it gets a bit confusing for me as this is my first time connecting through BT.

注意

发生这种情况时我发现的唯一修复"是关闭 BT 适配器,强制关闭程序,重新启动 BT 适配器并重新启动应用程序,由于显而易见的原因,这并不好.我尝试以编程方式重新启动适配器,但仍然无法连接.

The only "fix" I have found when this happens is to turn off the BT adapter, force close the program, restart BT adapter and restart app, which is not good for obvious reasons. I tried restarting the adapter programmatically but I still can't connect.

谁能看到我的 BlutoothService 类中可能有什么问题,这是 AcceptThread 所在的位置?或者我将如何解决这个问题?谢谢!

Can anyone see what might be wrong in my BlutoothService class, which is where AcceptThread is located? Or how I would go about resolving this issue? Thanks!

事实上,似乎连接有时在一个 Thread 上关闭并试图在另一个上重新连接.问题是我无法弄清楚是什么导致它尝试连接到单独的 Thread 或在发生这种情况时如何修复它.

It does, in fact, seem like the connection is sometimes closed on one Thread and trying to reconnect on another. The problem is that I can't figure out what would cause it to try and connect on a separate Thread or how to fix it when this happens.

我能成功重现的唯一方法是如果我的 BT 设备关闭,然后我关闭 BT 适配器.当我重新打开所有东西时,我收到异常并且无法连接.我有客户说它是随机和定期发生的,所以我希望这些问题是相关的.

The only way I can successfully reproduce this is if my BT device is turned off then I turn the BT adapter off. When I turn everything back on then I get the exception and cannot connect. I have customers that it happens to randomly and periodically so I'm hoping the issues are related.

推荐答案

嗯,我的部分问题是硬件问题,后来发现是第三方制造商端的问题.他们的固件不太正确,当它读取 BT 地址时,它偶尔会被损坏.

Well, part of my problem was a hardware issue that was found out to be a problem on the third-party manufacturers end. They're firmware wasn't quite right and when it was reading the BT address, it was occasionally being corrupted.

在软件方面,它定期在两个独立的Threads 中运行AcceptThread.我所做的修复是创建一个函数来关闭套接字和输入/输出流...

On the software side, it was running the AcceptThread in two separate Threads periodically. What I did to fix that was to create a function to close the socket and input/output streams...

public void closeAllConnections()
    {
        if (mmInStream != null)
        {
            try {mmInStream.close();}
            catch  (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
        }
        if (mmOutStream != null)
        {
            try {mmOutStream.close();}
            catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
        }
        if (mmSocket != null)
        {
          try {
                mmSocket.close();
                Log.e("TAG", "close() of connect socket successfu;");
              } catch (IOException e) {
                   Log.e("TAG", "close() of connect socket failed", e);}
        }

然后在 BluetoothCom 类中,我注意到在尝试重新启动服务之前并不总是检查 BT 对象是否为 null.

Then in the BluetoothCom class, I noticed it wasn't always checking for the BT object to be null before trying to restart the service.

private void setupService() {

    // Initialize the BluetoothChatService to perform bluetooth connections
    if((mChatService != null) && (mChatService.getState() != 0)) {
        mChatService.stop();        
    }

    // I didn't have this so it would always start a new instance of the Service
    if (mChatService == null)
        mChatService = new BluetoothService(mHandler);

    mChatService.start();
}

这似乎有所帮助,我不再遇到这些问题.但是,现在在三星 Galaxy Tab 4 上进行测试,我再次遇到连接问题,但仅限于该设备.也许这些信息可以帮助某人,如果我解决了新问题的其他问题,我会更新我的答案.

This seems to have helped and I no longer have those problems. However, now testing on the Samsung Galaxy Tab 4 and I am once again having connection issues but only on this device. Maybe this information can help someone and I will update my answer if I figure anything else out with the new problem.

注意:如上所述,此蓝牙应用程序使用来自 Android 的 BluetoothChat 应用程序的修改代码.

另外,我已经阅读(并注意到)不同的制造商以不同的方式实现 BT 堆栈,这可能会导致头痛(至少如果你对此不够了解的话).

Also, I have read (and noticed) that different manufacturers implement the BT stack differently which can lead to headaches (at least if yo don't know enough about it).

这篇关于接受线程上的 IOException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆