简体   繁体   中英

Java stream corrupted when sending strings over sockets

I keep getting the following error when I try to receive a new message from the socket: java.io.StreamCorruptedException: invalid type code: 00

I don't understand how or why this is happening, other stack overflow answers have been unhelpful, I've indicated the line in code where it gets thrown, any ideas? I'm using the same input streams and sockets streams to listen on all threads.

When a message is sent, the peer must 'mine' the message and send back the updated bloomchain to the original sender, the sender must then check this chain's validity, if it is valid it overwrites the local chain with the new chain.

// Any other ThreadPool can be used as well
    private ExecutorService cachedExecutor = null;
    private ExecutorService singleThreadExecutor = null;
    // port this client shall listen on
    private int port = 0;

    // Name of the client
    private String name = null;

    // indicates that a connection is ongoing
    private boolean isConnected = false;

    // the socket the Client is currently connected with
    private Socket activeConenctionSocket = null;

    // The ServerSocket which will be listening for any incoming connection
    private ServerSocket listener = null;

    // stream handles incoming blockchain data
    private static ObjectInputStream inputStream = null;

    // stream handles outgoing objects
    private static ObjectOutputStream outputStream = null;

    // local instance of the blockchain
    private BloomChain bloomChain = null;

    private Gson gson = null;



    /**
     * @param port Port number by which this client shall be accessed.
     * @param name The name of this Client.
     */
    public Client(int port, String name) {
        this.port = port;
        this.name = name;
        this.bloomChain = new BloomChain();

        this.cachedExecutor = Executors.newCachedThreadPool();
        this.singleThreadExecutor = Executors.newSingleThreadExecutor();

        this.listener = createListeningSocket();
        this.gson = new Gson();
        startListening();
    }



 /**
     * This method handles message sending
     * If it is the first message in a block then it creates a genesis block with a hash of '0'
     * Otherwise it adds a new block to the chain and sends it to the peer
     *
     * @param message
     */
    public void sendMessage(String message) {

        if (bloomChain.size() < 1) {
            System.out.println("Genesis Block");
            bloomChain.addBlock(new Block(message, "0"));

        } else {
            System.out.println("Augmented Block");
            bloomChain.addBlock(new Block(message, bloomChain.get(bloomChain.size() - 1).getPreviousHash()));
        }
        try {
            System.out.println("Sending Chain..");
            this.outputStream.writeObject(gson.toJson(bloomChain));
            this.outputStream.flush();
            System.out.println("Chain Sent..");
            try {
                bloomChain = updateLocalChain(); /**error begins here */
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * This sends the chain to a background thread in order to
     * mine the latest block and reveal the message
     *
     * @return once the mining is complete it returns the produced String
     */
    private String mineMessage(BloomChain bloomChain) {
        String receivedMessage = null;
        Block tempBlock = bloomChain.get(bloomChain.size() - 1);
        System.out.println(bloomChain.toString());
        tempBlock.mineBlock(bloomChain.getDifficulty());
        System.out.println(bloomChain.toString());
        if (bloomChain.isValid()) {
            receivedMessage = tempBlock.getData();
            this.bloomChain = bloomChain;
            try {
                this.outputStream.writeObject(gson.toJson(this.bloomChain));
                this.outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println(receivedMessage);
        } else {
            receivedMessage = "Chain Invalid";
        }

        return receivedMessage;
    }

    /**
     * This method is continuously called (in the main() class)
     * This listens for any incoming messages
     *
     * @return returns the mineMessage() result
     */
    public String dataListener() {
        try {
            String tempChain = (String) this.inputStream.readObject();
            return mineMessage(this.gson.fromJson(tempChain, BloomChain.class));
        } catch (Exception e) {
            //This will produce exceptions until the client has connected to a peer
            //so no logic is present here
        }
        return null;
    }

    private void checkChainValidity(BloomChain tempChain) {
        if(tempChain.isValid()){
            System.out.println("Local Chain Updated");
            System.out.println(this.bloomChain.toString());
            this.bloomChain = tempChain;
        }
    }

    public ServerSocket getListener() {
        return this.listener;
    }

    private synchronized BloomChain updateLocalChain() throws ExecutionException, InterruptedException {
        Future<BloomChain> agreedChain = this.singleThreadExecutor.submit(new Callable<BloomChain>() {
            @Override
            public BloomChain call() throws IOException, ClassNotFoundException {
                String newChain = (String) inputStream.readObject();
                return gson.fromJson(newChain, BloomChain.class);
            }
        });
        return agreedChain.get(); /** ERROR IS THROWN HERE */
    }


}

Stack Trace:

java.util.concurrent.ExecutionException: java.io.StreamCorruptedException: invalid type code: 00
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at com.p2p.Client.updateLocalChain(Client.java:265)
    at com.p2p.Client.sendMessage(Client.java:186)
    at com.gui.ClientGUI$4.actionPerformed(ClientGUI.java:78)
    at javax.swing.JTextField.fireActionPerformed(JTextField.java:508)
    at javax.swing.JTextField.postActionEvent(JTextField.java:721)
    at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:836)
    at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1663)
    at javax.swing.JComponent.processKeyBinding(JComponent.java:2882)
    at javax.swing.JComponent.processKeyBindings(JComponent.java:2929)
    at javax.swing.JComponent.processKeyEvent(JComponent.java:2845)
    at java.awt.Component.processEvent(Component.java:6310)
    at java.awt.Container.processEvent(Container.java:2237)
    at java.awt.Component.dispatchEventImpl(Component.java:4889)
    at java.awt.Container.dispatchEventImpl(Container.java:2295)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:835)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1103)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:974)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:800)
    at java.awt.Component.dispatchEventImpl(Component.java:4760)
    at java.awt.Container.dispatchEventImpl(Container.java:2295)
    at java.awt.Window.dispatchEventImpl(Window.java:2746)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
    at java.awt.EventQueue$4.run(EventQueue.java:733)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.io.StreamCorruptedException: invalid type code: 00
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1595)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427)
    at com.p2p.Client$1.call(Client.java:261)
    at com.p2p.Client$1.call(Client.java:258)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

Not a direct answer(sorry could not comment) If you are about just send and receive strings, then use BufferedReader in client, while you may use PrintWriter or StreamWriter in server.

Please also share the server code. Maybe you are sending wrong object from server.

Also please check if the order of the data you send from server is same/sync with the client.

For integrity, you may go for pure byte streaming over object streaming, or using common formats like JSON/XML .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM