簡體   English   中英

套接字編程中的代碼卡在readLine()中

[英]Code stucks in readLine() in socket programming

我是套接字編程的新手。 我從教程中復制了Java服務器客戶端代碼,在該教程中,客戶端將字符串發送到服務器,服務器將字符串大寫並將其發送回客戶端。

我有一個JTextField,其中輸入了要大寫的字符串,還有一個JTextArea,其中顯示了大寫的字符串輸出。

但是問題是當我在JTextField中輸入內容並按Enter時,代碼掛起。 通過調試,我發現當客戶端嘗試使用readLine()讀取服務器發送的大寫字符串時,代碼已掛起。

我不知道如何擺脫它。 我已經在Stack Overflow中閱讀了幾個類似的問題,並嘗試了解決方案,但沒有希望。

服務器代碼:

public class CapitalizeServer {

/**
 * @param args the command line arguments
 * @throws java.io.IOException
 */
public static void main(String[] args) throws IOException {
    System.out.println("The Capitalization Server is running");

    int clientNumber = 0;
    try (ServerSocket listener = new ServerSocket(1234)) {
        while(true) {
            new Capitalizer(listener.accept(), clientNumber++).start();
        } 
    }
} 

private static class Capitalizer extends Thread {

    Socket socket;
    int clientNumber;

    public Capitalizer(Socket socket, int clientNumber) {
        this.socket = socket;
        this.clientNumber = clientNumber;
        log("New connection with client# " + clientNumber + " at " + socket);  
    }

    @Override
    public void run() {
        try {

            // Decorate the streams so we can send characters
            // and not just bytes.  Ensure output is flushed
            // after every newline.
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

            // Send a welcome message to the client.
            out.println("Hello, you are client # " + clientNumber + ".");
            out.println("Enter a line with only a period to quit");

            // Get messages from the client, line by line; return them capitalized
            while(true) {
                String input = in.readLine();
                if(input == null || input.equals(".")) {
                    break;
                }

                //System.out.println("Coming input: " + input);
                out.println(input.toUpperCase());
                //System.out.println("UpperCase: " + input.toUpperCase());
            }

        } catch (IOException ex) {
            log("Error handling client# " + clientNumber + ": " + ex );

        } finally {
            try {
                socket.close();
            } catch (IOException ex) {
                log("Could not close a socket. What's going on?");
            }

            log("Connection with client# " + clientNumber + " closed");
        }
    }

    /**
     * Logs a simple message.  In this case we just write the
     * message to the server applications standard output.
     */
    private void log(String message) {
        System.out.println(message);
    }
}

}

客戶代碼:

public class CapitalizeClient {

private BufferedReader in;
private PrintWriter out;
private JFrame frame = new JFrame("Capitalize Client");
private final JTextField dataField = new JTextField(40);
private final JTextArea messageArea = new JTextArea(8,60);    
/**
 * Constructs the client by laying out the GUI and registering a
 * listener with the textField so that pressing Enter in the
 * listener sends the textField contents to the server.
 */
public CapitalizeClient() {

    // Layout GUI
    messageArea.setEditable(false);
    frame.getContentPane().add(dataField, "North");
    frame.getContentPane().add(new JScrollPane(messageArea), "Center");

    // Add Listeners
    dataField.addActionListener(new ActionListener() {

        /**
         * Responds to pressing the enter key in the textField
         * by sending the contents of the text field to the
         * server and displaying the response from the server
         * in the text area.  If the response is "." we exit
         * the whole application, which closes all sockets,
         * streams and windows.
         */
        @Override
        public void actionPerformed(ActionEvent e) {
            out.println(dataField.getText());
            String response;

            try {
    // ******* The code stucks here *************
                response = in.readLine();

                if(response == null) {
                    System.exit(0); 
                } 
            } catch (IOException ex) {
                response = "Error: " + ex;
            }
            messageArea.append(response + "\n");
            dataField.selectAll();
        } 
    });
}

public void connectToServer() throws IOException {

    // Get the server address from a dialog box.
    String serverAddress = JOptionPane.showInputDialog(frame,  "Enter IP Address of the Server:" ,
        "Welcome to the Capitalization Program", JOptionPane.QUESTION_MESSAGE); 

    // Make connection and initialize streams
    Socket socket = new Socket(serverAddress, 1234);
    in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    out = new PrintWriter(socket.getOutputStream(), true);

    // Consume the initial welcoming messages from the server
    for(int i=0; i < 3; i++) {
        messageArea.append(in.readLine() + "\n");
    }  
}

public static void main(String[]args) throws IOException {
    CapitalizeClient client = new CapitalizeClient();
    client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    client.frame.pack();
    client.frame.setVisible(true);
    client.connectToServer();
}

}

您的問題是在客戶端。 替換方法代碼

public void connectToServer() throws IOException {

    // Get the server address from a dialog box.
    String serverAddress = JOptionPane.showInputDialog(frame, "Enter IP Address of the Server:",
            "Welcome to the Capitalization Program", JOptionPane.QUESTION_MESSAGE);

    // Make connection and initialize streams
    Socket socket = new Socket(serverAddress, 1234);
    in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    out = new PrintWriter(socket.getOutputStream(), true);

    // Consume the initial welcoming messages from the server
    for (int i = 0; i < 2; i++) {
        messageArea.append(in.readLine() + "\n");
    }
}

您只需要遍歷循環兩次,因為歡迎消息是兩行而不是三行。

通信始終需要同步。 如果從服務器發送兩行,則在發送內容之前,需要在客戶端上閱讀兩行。

暫無
暫無

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

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