在java

时间:2016-09-27 16:28:34

标签: java sockets serversocket

我在这里读过类似的帖子,但无法理解什么是解决方案。

我有服务器为每个客户端创建新线程。线程是:

private static class Capitalizer extends Thread {
        private Socket socket;
        private int clientNumber;

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

        private void log(String message) {
            System.out.println(message);
        }

        @Override
        public void run() {
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

                out.println("Hello, you are a client " + clientNumber);
                out.println("Enter a line with only a period to exit");

                while (true) {
                    String line = in.readLine();
                    if (line == null || line.equals("."))
                        break;
                    out.println(line.toUpperCase());
                    System.out.println("Server capitalized " + line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                log("Connection with client " + clientNumber + " is closed");
            }
        }
    }

客户是:

public class CapitalizeClient {
    private BufferedReader in;
    private PrintWriter out;
    private JFrame mainWindow = new JFrame("Capitalize Client");
    private JTextField dataField = new JTextField(40);
    private JTextArea messageArea = new JTextArea(8, 60);

    public CapitalizeClient() {

        messageArea.setEditable(false);
        mainWindow.getContentPane().add(dataField, BorderLayout.NORTH);
        mainWindow.getContentPane().add(new JScrollPane(messageArea));

        dataField.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                String text = dataField.getText();
                out.println(text);
                System.out.println("text is sent to server");
                try {
                    String upperCased = in.readLine();
                    if (upperCased == null || upperCased.equals("."))
                        System.exit(0);
                    System.out.println("ActionListener " + text);
                    messageArea.append(upperCased + "\n");
                    dataField.selectAll();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        });
    }

    private void connectToServer() throws UnknownHostException, IOException {
        String serverAddress = JOptionPane.showInputDialog(mainWindow, "Enter word 'localhost'",
                "Welcome to the capitalization program", JOptionPane.QUESTION_MESSAGE);

        Socket socket = new Socket(serverAddress, CapitalizeServer.port);

        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out = new PrintWriter(socket.getOutputStream(), true);

        String line;
        while ((line = in.readLine()) != null) {
            messageArea.append(line + "\n");
        }

    }

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

Capitalizer线程运行正常,但dataField的ActionListener会一直运行,直到它记录消息text is sent to server

该程序挂起后:

String upperCased = in.readLine();
<{1>} ActionListener中的

为什么? 谢谢!

2 个答案:

答案 0 :(得分:0)

您需要刷新服务器中的OutputStream

out.println(line.toUpperCase());
out.flush();

答案 1 :(得分:0)

您可以尝试使用read()方法从服务器获取响应,如下所示:

    int i;
    char[] chars = new char[1024];
    while ((i = in.read(chars,0,1024)) != -1) 
    {
         messageArea.append(String.valueOf(chars) + "\n");
    }

一旦从服务器端发送了数据流,即在您的大写模式中,请关闭OutputStream,完成后添加out.close()