我是套接字编程的新手。我从教程中复制了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");
    }
}


您只需要遍历循环两次,因为您的欢迎消息是两行而不是三行。

通信始终需要同步。如果从服务器发送两行,则在发送内容之前,需要在客户端上阅读两行。

关于java - 套接字编程中的代码卡在readLine()中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43907012/

10-12 06:30