簡體   English   中英

Java套接字writeObject卡住

[英]Java socket writeObject stucks

我正在嘗試創建一些本地聊天軟件。 一切工作正常,但只停留在一點上; 當用戶單擊按鈕時,我的程序卡住了。

我寫了一個修改后的類,它對服務器和客戶端都起作用。

下面是我的代碼:

package connections;

import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.channels.SocketChannel;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import ui.ChatWindow;

public class Chat{

private SocketChannel socketChannel;
private ConnectionType connectionType;

private ObjectOutputStream out;
private ObjectInputStream in;

private String strClientName;

private ChatWindow chatWindow;
private String strMessage;

public Chat(SocketChannel socketChannel, ConnectionType connectionType) {
    this.socketChannel = socketChannel;
    this.connectionType = connectionType;

    init();
}

private void init() {

    new Thread(this::initThread).start();
}

private void initThread() {
    try {
        out = new ObjectOutputStream(socketChannel.socket().getOutputStream());
        in = new ObjectInputStream(socketChannel.socket().getInputStream());

        if (connectionType == ConnectionType.SERVER) {
            getClientName();
            sendMyName();
        } else {
            sendMyName();
            getClientName();
        }

        chatWindow = new ChatWindow();
        chatWindow.btnSend.addActionListener(this::eventBtnSend);
        chatWindow.setTitle(strClientName);
        chatWindow.setSize(600, 400);
        chatWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        if (connectionType == ConnectionType.CLIENT) {
            chatWindow.setVisible(true);
            chatWindow.requestFocus();
        }

        System.out.println("here");

        beginChat();

        System.out.println("thread ends");

    } catch (IOException ex) {
        Logger.getLogger(Chat.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private void getClientName() {

    try {
        strClientName = (String) in.readObject();
    } catch (IOException | ClassNotFoundException ex) {
        Logger.getLogger(Status.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private void sendMyName() {

    try {
        out.writeObject(main.Config.myName);
        out.flush();
    } catch (IOException ex) {
        Logger.getLogger(Status.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private void beginChat() {
    while (true) {
        try {                
            waitForMessage();
        } catch (IOException | ClassNotFoundException ex) {
            Logger.getLogger(Chat.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

private void waitForMessage() throws IOException, ClassNotFoundException {
    System.out.println("waiting for Message : " + connectionType);
    strMessage = (String) in.readObject();
    System.out.println("Message received");
    chatWindow.txtDisplay.append(strClientName + " : " + strMessage + "\n");

    if(chatWindow.isVisible() == false){
        chatWindow.setVisible(true);
    }
}

private void sendMessage(String strMessage) {

    try {
        out.writeObject(strMessage);
        out.flush();
    } catch (IOException ex) {
        Logger.getLogger(Chat.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private void eventBtnSend(ActionEvent ae){
    System.out.println("a");
    sendMessage(chatWindow.txtMessage.getText());
    System.out.println("b");
    chatWindow.txtDisplay.append("Me : " + chatWindow.txtMessage.getText() + "\n");
    System.out.println("c");
    chatWindow.txtMessage.setText("");
}
}

當服務器和客戶端連接時,我可以看到以下輸出:

here
waiting for Message : SERVER
here
waiting for Message : CLIENT

但是,當我單擊發送按鈕時,我的程序卡住了。 單擊按鈕后,我可以看到:

a on console.

這個詞是“塊”。 它阻止了I / O。 它會阻塞。

不要在事件線程上執行阻塞操作。 所有網絡代碼都應在單獨的線程上運行。 其中包括readObject()writeObject(),以及flush(),還創建了流。

暫無
暫無

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

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