read()和readObject()

时间:2015-06-21 12:32:05

标签: java android sockets bluetooth

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

/**
 * 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,首先我尝试读取字符串,然后在第二个我的对象中。如何区分run-method中的String和Objects? 我是套接字的新手,inputStreamoutputStream ..

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

1 个答案:

答案 0 :(得分:-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);
    }