簡體   English   中英

通過套接字發送字符串時Java流損壞

[英]Java stream corrupted when sending strings over sockets

嘗試從套接字接收新消息時,我不斷收到以下錯誤: java.io.StreamCorruptedException: invalid type code: 00

我不明白這種情況的發生方式或原因,其他堆棧溢出答案都無濟於事,我已經在代碼中指出了拋出該行的地方,有什么想法嗎? 我正在使用相同的輸入流和套接字流來偵聽所有線程。

發送消息時,對等方必須“挖掘”消息並將更新的bloomchain發送回原始發送者,然后發送者必須檢查此鏈的有效性,如果有效,它將用新鏈覆蓋本地鏈。

// 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 */
    }


}

堆棧跟蹤:

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)

不是直接的答案(對不起,無法評論)如果您只是發送和接收字符串,請在客戶端中使用BufferedReader ,而在服務器中則可以使用PrintWriterStreamWriter

還請共享服務器代碼。 也許您是從服務器發送了錯誤的對象。

另外,請檢查從服務器發送的數據順序是否與客戶端相同/同步。

為了完整性,您可以通過對象流或使用諸如JSON/XML通用格式進行純字節流。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM