【问题标题】:Problems with read() and readObject()read() 和 readObject() 的问题
【发布时间】:2015-06-21 12:32:05
【问题描述】:

我尝试开发一款通过蓝牙玩 1vs1 的纸牌游戏。我已经连接了设备,现在我有一个问题:我想发送对象抛出蓝牙。 如果我只制作对象,它就可以工作,如果只制作字符串,它就可以工作。 但如果我尝试同时制作两者,我就有问题了。

/**
 * This thread runs during a connection with a remote device.
 * It handles all incoming and outgoing transmissions.
 */
private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;

    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    // for Objects
    private final ObjectInputStream mObjectInStream;
    private final ObjectOutputStream mObjectOutStream;

    public ConnectedThread(BluetoothSocket socket) {
        if (D) Log.d(TAG, "create ConnectedThread");
        mmSocket = socket;

        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        ObjectInputStream tmpObjIn = null;
        ObjectOutputStream tmpObjOut = null;

        // Get the BluetoothSocket input and output streams
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();

            tmpObjOut = new ObjectOutputStream(socket.getOutputStream());
            tmpObjOut.flush();
            tmpObjIn = new ObjectInputStream(socket.getInputStream());

        } catch (IOException e) {
            Log.e(TAG, "temp sockets not created", e);
        }


        mmInStream = tmpIn;
        mmOutStream = tmpOut;

        mObjectOutStream = tmpObjOut;
        mObjectInStream = tmpObjIn;
    }

    public void run() {
        if (D) Log.i(TAG, "BEGIN mConnectedThread");
        byte[] buffer = new byte[1024];
        int bytes;


        // Keep listening to the InputStream while connected
        while (true) {

                try {

                    // Read from the InputStream
                    bytes = mmInStream.read(buffer);

                    // Send the obtained bytes to the UI Activity
                    mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
                            .sendToTarget();

                } catch (IOException e) {
                    Log.e(TAG, "disconnected", e);
                    connectionLost();
                    // Start the service over to restart listening mode
                    BluetoothService.this.start();
                    break;
                }

                try {

                    // Send the obtained Object to the UI Activity
                    mHandler.obtainMessage(Constants.MESSAGE_READ_OBJECT, -1, -1, mObjectInStream.readObject())
                            .sendToTarget();

                } catch (IOException e) {
                    Log.e(TAG, "disconnected", e);
                    connectionLost();
                    // Start the service over to restart listening mode
                    BluetoothService.this.start();
                    break;
                } catch (ClassNotFoundException cn) {
                    Log.e(TAG, "Class not found", cn);
                }
            }

    }


    /**
     * Write to the connected OutStream.
     *
     * @param buffer The bytes to write
     */

    public void writeString(byte[] buffer) {
        try {

            mmOutStream.write(buffer);

            // Share the sent message back to the UI Activity
            mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)
                    .sendToTarget();
        } catch (IOException e) {
            Log.e(TAG, "Exception during write", e);
        }
    }

    /**
     * Write an Object (Serializable) to the connected OutStream.
     *
     * @param object The object to write
     */
    public void writeObject(Object object) {
        try {

            mObjectOutStream.writeObject(object);

            // Share the sent message back to the UI Activity

            // TODO hier unterscheiden zwischen Player und UnoKarte?
            mHandler.obtainMessage(Constants.MESSAGE_WRITE_OBJECT, -1, -1, object)
                    .sendToTarget();
        } catch (IOException e) {
            Log.e(TAG, "Exception during write", e);
        }
    }


    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "close() of connect socket failed", e);
        }
    }
}

错误:

06-21 14:18:44.580  10941-11034/? E/BluetoothService﹕ disconnected
java.io.StreamCorruptedException: Wrong format: 0
        at java.io.ObjectInputStream.corruptStream(ObjectInputStream.java:830)
        at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:943)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2262)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2217)
        at com.example.thm_wip1.uno.BluetoothService$ConnectedThread.run(BluetoothService.java:550)

第 550 行是:mHandler.obtainMessage(Constants.MESSAGE_READ_OBJECT, -1, -1, mObjectInStream.readObject())


While(true) 中我有两个try-catch,第一个我尝试读取字符串,第二个我的对象。如何区分运行方法中的字符串和对象? 我是套接字新手,inputStreamoutputStream..

如果您需要更多详细信息,我会编辑我的问题。

【问题讨论】:

  • 这实际上可能是由多种原因引起的,以这种方式向我们展示您的代码并不是很有用,您能否向我们展示您对 writeObject 的函数调用以及您如何实例化该类? - 编辑我发现你的问题我相信。

标签: java android sockets bluetooth


【解决方案1】:

当您在设备的内部一致性检查中读取标头不一致时会发生 StreamCorruptedException,在您的情况下,一致性检查失败是因为您尝试使用多个输出流和输入流,第一个在 tmpout 和 tmpin 中定义,然后您尝试再次从不同的输出流和输入流创建 ObjectOutputStreams 和 ObjectinputStreams。这些会导致标题不一致。

应该解决这个问题的正确代码如下

 try {
        tmpIn = socket.getInputStream();
        tmpOut = socket.getOutputStream();

        tmpObjOut = new ObjectOutputStream(tmpOut);
        tmpObjOut.flush();
        tmpObjIn = new ObjectInputStream(tmpIn);

    } catch (IOException e) {
        Log.e(TAG, "temp sockets not created", e);
    }

【讨论】:

  • 这正是他已经在做的事情。多个流会导致invalid type code: AC
  • @EJP 如果您清楚地查看他的代码,与我的代码相比,这不是一回事,他调用 socket.getInputStream() 两次,一次在 tmpIn 中,另一次在 tmpObjIn 中,这就是为什么他有一个损坏的蓝牙流。这是那个家伙的代码的解决方案,经过测试和彻底。在投反对票之前请仔细阅读代码:)。
猜你喜欢
  • 2019-02-27
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-11
  • 1970-01-01
相关资源
最近更新 更多