了解printwwriter和flush的需求



首先,我为所有的代码道歉,但我觉得代码太多总比不够好。我正在制作一个简单的聊天客户端和打印机,特别是我正在努力。有了代码,现在它将与服务器类交互,并完美地打印我想要打印的内容。然而,当我删除'writer.flush();'时,它将停止打印。根据我的理解-这显然是错误的- 'writer.println(outgoing.getText());'应该足够了,因为这将发送我试图发送到服务器的文本。我理解flush强制所有的信息写,但为什么这是必需的,当我已经写了我想写什么?

public class SimpleChatClientA {
    JTextArea incoming;
    JTextField outgoing;
    BufferedReader reader;
    PrintWriter writer;
    Socket sock;
    public void go(){
        JFrame frame = new JFrame("Ludicrously Simple Chat Client");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel mainPanel = new JPanel();
        incoming = new JTextArea(15,50);
        incoming.setLineWrap(true);
        incoming.setWrapStyleWord(true);
        incoming.setEditable(false);
        JScrollPane qScroller = new JScrollPane(incoming);
        qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        outgoing = new JTextField(20);
        JButton sendButton = new JButton("Send");
        sendButton.addActionListener(new SendButtonListener());
        mainPanel.add(qScroller);
        mainPanel.add(outgoing);
        mainPanel.add(sendButton);
        setUpNetworking();
        Thread readerThread = new Thread(new IncomingReader());
        readerThread.start();
        frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
        frame.setSize(400, 500);
        frame.setVisible(true);

    }//close go
    public void setUpNetworking(){
        try{
            sock = new Socket("127.0.0.1", 5000);
            InputStreamReader streamReader = new InputStreamReader(sock.getInputStream());
            reader = new BufferedReader(streamReader);
            writer = new PrintWriter(sock.getOutputStream());
            System.out.println("network established");
        }catch(Exception e){
            e.printStackTrace();
        }
    }//close setupnetworking
    public class SendButtonListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            try{
                writer.println(outgoing.getText());
                writer.flush();
            }catch(Exception ex){
                ex.printStackTrace();
            }
            outgoing.setText("");
            outgoing.requestFocus();
        }
    }//close sendbuttonlistener inner class

    public class IncomingReader implements Runnable{
        public void run(){
            String message;
            try{
                while((message = reader.readLine()) != null){
                    System.out.println("read " + message);
                    incoming.append(message + "n");
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }//close inner class incomingreader

    public static void main(String[] args){
        new SimpleChatClientA().go();
    }

}

提前感谢,如果有更多的信息我可以给请让我知道第一次我已经正确地张贴到stackoverflow

只有启用了autoFlush属性,PrintWriter类的println()方法才会向流"提交"数据。

看这段引用自Java文档:

如果启用了自动刷新,则只有在调用println、printf或format方法之一时才会执行刷新

链接到Java文档:https://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html#PrintWriter(java.io.OutputStream,%20boolean)

如果需要将消息发送到服务器,则创建启用自动刷新选项的PrintWriter对象。

那么,在创建writer对象的地方,只需这样做:

writer = new PrintWriter(sock.getOutputStream(), true);

应该可以了。希望能有所帮助!

在每个println之后不刷新数据会更有效。如果您正在写入大量数据,您希望对其进行缓冲并以大块的形式发送,而不是单独发送每一行。这就是为什么你需要手动刷新流,如果你想确保数据确实被发送到另一端。

想象一下你正在给朋友写一封电子邮件,你把每个单词作为一个单独的电子邮件发送,而不是在一封电子邮件中发送整个文本。你认为哪个更快?当然,如果你按照自己的想法发送每个单词,你的朋友可以更快地阅读邮件,但总花费的时间会更长。

相关内容

  • 没有找到相关文章

最新更新