java - 有人可以帮我理解以下代码中的服务器如何在java中工作吗

标签 java client

这是一个简单的聊天服务器和客户端,我从我读过的一本书中得到,我在理解一些代码时遇到了困难,有人可以帮助我解决这个问题

这是客户端代码

public class ChatClient {
JTextArea incoming;
JTextField outgoing;
BufferedReader reader;
PrintWriter writer;
Socket sock;

public static void main(String[] args) {
    ChatClient client = new ChatClient();
    client.go();

}

public void go() {
    JFrame frame = new JFrame();
    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(sendButtonListener);
    mainPanel.add(qScroller);
    mainPanel.add(outgoing);
    mainPanel.add(sendButton);
    setUpNetworking();
    Thread readerThread = new Thread(new IncomingReader());
    readerThread.start();
    frame.add(mainPanel);
    frame.setSize(400, 500);
    frame.setVisible(true);

}

private 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("connected");
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

ActionListener sendButtonListener = new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
        writer.println(outgoing.getText());
        writer.flush();
        outgoing.setText("");
        outgoing.requestFocus();

    }

};

public class IncomingReader implements Runnable {

    @Override
    public void run() {
        String message;
        try {
            while ((message = reader.readLine()) != null) {

                System.out.println("read " + message);
                incoming.append(message + "\n");
            }

            System.out.println("ggggggggg");

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

}

我无法理解的部分是:

public void run() {
        String message;
        try {
            while ((message = reader.readLine()) != null) {

                System.out.println("read " + message);
                incoming.append(message + "\n");
            }



        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

在这一部分中,只要我们从服务器读取的内容不为空,代码就会运行,我的问题是,一旦我们启动线程,我们从服务器读取的第一件事不会是空,因为我们还没有写入任何东西,因此,打破循环? 就像消息何时等于 Null?

这是服务器代码,供任何想要阅读的人使用

public class ChatServer {
ArrayList clientOutputStreams;

public class ClientHandler implements Runnable {
    BufferedReader reader;
    Socket sock;

    public ClientHandler(Socket clientSocket) {
        try {
            sock = clientSocket;
            InputStreamReader isReader = new InputStreamReader(
                    sock.getInputStream());
            reader = new BufferedReader(isReader);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void run() {
        String message;
        try {
            while ((message = reader.readLine()) != null) {
                System.out.println("read " + message);
                tellEveryone(message);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

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

public void go() {
    clientOutputStreams = new ArrayList();
    try {
        ServerSocket serverSock = new ServerSocket(5000);
        while (true) {
            Socket clientSocket = serverSock.accept();
            PrintWriter writer = new PrintWriter(
                    clientSocket.getOutputStream());
            clientOutputStreams.add(writer);
            Thread t = new Thread(new ClientHandler(clientSocket));
            t.start();
            System.out.println("got a connection");
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public void tellEveryone(String message) {
    Iterator it = clientOutputStreams.iterator();
    while (it.hasNext()) {
        try {
            PrintWriter writer = (PrintWriter) it.next();
            writer.println(message);
            writer.flush();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

}

对我来说更合乎逻辑的方法是有一个 while true 循环并一直检查服务器以等待这样的消息:

while(true){
    if ((message = reader.readLine()) != null){
        System.out.println("read " + message);
        incoming.append(message + "\n");
    }
}

最佳答案

won't the first thing that we read from the server as soon as we start the thread would be Null since we haven't written any thing to it yet

我认为您已经部分回答了自己的问题。当到达 EOF 时,BufferedReader#read 返回 null,因此,由于尚未到达 EOF 标记,因此 read 方法将阻塞,直到有内容要读取或达到 EOF 为止。

来自JavaDocs ...

public String readLine()
throws IOException

Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.

Returns:
A String containing the contents of the line, not including any line-termination > characters, or null if the end of the stream has been reached

循环实际上是无限的。唯一会中断的方法是关闭底层流,这可能会导致 IOException

你从哪本书上得到的?这不是一个很好的例子

关于java - 有人可以帮我理解以下代码中的服务器如何在java中工作吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25196877/

相关文章:

java - JAXB UnMarshal Collection 元素顺序

java - 为什么这个 Observable.timer() 会导致内存泄漏?

java - C++ 客户端连接到非阻塞 Java NIO 服务器

java - 如何运行 oracle 客户端服务器教程?

javascript - Ruby 客户端 Eventbrite API 使用 Javascript 查找事件 ID

java - Spinner 不会响应点击……即使调用了 onItemSelected?

java - 执行WAR文件时出错

java - Android开发与hibernate+spring

events - 事件处理程序和事件监听器之间有什么区别(如果有)?

node.js - 如何在没有机器人的情况下在 node.js 中接收我自己的 Telegram 消息