java - 输出被打印两次

标签 java sockets system.out

我正在尝试使用套接字来对客户端和服务器交互进行编程。用户可以阅读他们的消息、给某人撰写消息,然后退出。一切正常,除了“没有消息”打印两次而不是一次,我不明白为什么。我将把相关代码放在下面,任何帮助都会很棒。谢谢!

客户端.java

     import java.io.*;
import java.net.*;

public class Client {

    public static void main(String[] args) {

    String messages = "";

    // Makes sure there are only two arguments entered

        if(args.length != 2) {
            System.err.println("Usage: java Client <host name> <port number>");
            System.exit(1);
        }

        // Stores the command line arguments for readability further in the program
        String host = args[0];
        int port = Integer.parseInt(args[1]);

        try (

            // Creates the socket to be used
            Socket s = new Socket(host, port);

            // Reader and Writer to talk with Server
            PrintWriter pw =
                        new PrintWriter(s.getOutputStream(), true);
            BufferedReader bf = new BufferedReader(
                        new InputStreamReader(s.getInputStream()));
        ) {

            // Reader to read from standard input (keyboard)
            BufferedReader keyboard =
                        new BufferedReader(new InputStreamReader(System.in));


        // User interface
        while (true) {

        System.out.println("Please enter your username: ");
        String username = keyboard.readLine();

            // Check that the login is valid
            if (username == null) {
            System.out.println("No username entered");
            }
            else if (username.contains(" ")) {
            System.out.println("Username cannot contain spaces");
            }
                // Send username to server and return number of messages
            else {
                pw.println(username);
            messages = bf.readLine();
            System.out.println("You have " + Integer.parseInt(messages) + " messages");
            break;
            }
        }

        // Enable the user to continue reading and composing messages until
        // they choose to exit
        while (true) {
            System.out.println("Would you like to READ, COMPOSE or EXIT?");
            String choice = keyboard.readLine();

        // Shows the messages left for the user
                if (choice.equals("READ")) {
            pw.println("READ");
            messages = bf.readLine();
                    if (Integer.parseInt(messages) == 0) {
                        System.out.println("NO MESSAGES");
            }
            else {
            String incoming = bf.readLine();
            System.out.println(incoming);
                        incoming = bf.readLine();
            System.out.println(incoming);
            }
            }
        // Allows user to write a message to another user
            else if (choice.equals("COMPOSE")) {
            pw.println("COMPOSE");
            // I've separated this into two lines for readability
            System.out.println("Enter message recipient");
            String recipient = keyboard.readLine();
            if (recipient == null) {
                System.out.println("No recipient username entered");
                }
                else if (recipient.contains(" ")) {
                System.out.println("Recipient username cannot contain spaces");
                }
            else {
            pw.println(recipient);
                        System.out.println("Enter message to be sent");
                String im = keyboard.readLine();
                pw.println(im);
            System.out.println(bf.readLine());
            }
            }
            else if (choice.equals("EXIT")) {
            pw.println("EXIT");
            System.exit(1);
            }
            else {
                    System.out.println("Error: you must either READ, COMPOSE or EXIT");
            }
        }

        }    


        // Catches the exception in which the server cannot be found
        catch(IOException e) {

            System.out.println("Error, could not connect to Server");
            System.exit(1);
        }
    }
}

服务器.java

    import java.io.*;
import java.net.*;

public class Server {

        public static void main(String[] args) {

        String request;

            // Makes sure that the user has specified the correct number of command line arguments
            if(args.length != 1) {
                System.err.println("Usage: java Server <port number>");
                System.exit(1);
            }
            int port = Integer.parseInt(args[0]);

            try (
            // Creates a server socket and waits for a connection
                ServerSocket ss = new ServerSocket(port);

                // A socket to communicate with the client
                Socket cs = ss.accept();

                // Reader and Writer to talk with Client
                PrintWriter pw =
                            new PrintWriter(cs.getOutputStream(), true);
                BufferedReader bf = new BufferedReader(
                            new InputStreamReader(cs.getInputStream()));
            )

                // Links the server to the protocol     
            {
            Protocol protocol = new Protocol();
            protocol.storeUsername(bf.readLine());
            pw.println(protocol.messagesNumber());

            // Loop through user input until EXIT is entered
                while (true) {
                request = bf.readLine();
                // Controls output if user inputs READ
                if (request.equals("READ")) {
                    pw.println(protocol.messagesNumber());
                    if (protocol.messagesNumber() != 0) {
                        pw.println(protocol.readSender());
                        pw.println(protocol.readMessage());
                    }
                }
                // Controls input if user inputs COMPOSE
                else if (request.equals("COMPOSE")) {
                    String sender = bf.readLine();
                    String message = bf.readLine();
                    if (protocol.append(sender, message)) {
                    pw.println("MESSAGE SENT");
                }
                    else {
                    pw.println("MESSAGE FAILED");
                }
                }
                // Exits the server
                else {
                    System.exit(1);
                }
            }
            }


              // Catches the exception in which the server cannot find a client
              catch(IOException e) {
                  System.out.println("Failed to find a client");
                  System.exit(1);
              }      


       }
    }

协议(protocol).java

import java.net.*;
import java.io.*;
import java.util.*;

public class Protocol {
    private String username;
    private String recipient;
    private String sender;
    private HashMap<String, ArrayList<String>> senderMap = new HashMap<String, ArrayList<String>>();
    private HashMap<String, ArrayList<String>> messageMap = new HashMap<String, ArrayList<String>>();


    // Stores the username for the logged in user
    public void storeUsername(String user) {
    username = user;
    }

    // Stores the recipient name
    public void storeRecipient(String name) {
        recipient = name;
    }

    // Returns how many messages the logged in user has
    public int messagesNumber() {
    if(messageMap.containsKey(username))
        return messageMap.get(username).size();
    else
        return 0;
    }

    public boolean append(String recipient, String message) {
    boolean success = false;
    // If there is an entry for that name, just add the message to the end
        if(messageMap.containsKey(recipient)) {
        senderMap.get(recipient).add(username);
        messageMap.get(recipient).add(message);
        success = true;
        }
    // If there is no entry for that name, create a new entry with a list of messages and add the first message
    else {
        senderMap.put(recipient, new ArrayList<String>());
        senderMap.get(recipient).add(username);
        messageMap.put(recipient, new ArrayList<String>());
        messageMap.get(recipient).add(message);
        success = true;
    }
    return success;             
    }

     public String readSender() {

    // If the user has an entry and has at least 1 sender, return the least recent sender and then remove it  (the sender first in the list)
        if(senderMap.containsKey(username)) {

            if(senderMap.get(username).size() > 0) {
            String temp = senderMap.get(username).get(0);
            senderMap.get(username).remove(0);
            return temp;
        }
            else
            // If there are no messages left to read
            return "NO MESSAGES";
        }
        else
        // If the login hasn't been created yet
            return "NO MESSAGES";
    }


    public String readMessage() {

    // If the user has an entry and has at least 1 unread message, return the least recent unread message and then remove it (the first  message in the list)
        if(messageMap.containsKey(username)) {

            if(messageMap.get(username).size() > 0) {
            String temp = messageMap.get(username).get(0);
            messageMap.get(username).remove(0);
            return temp;
        }
            else
            // If there are no messages left to read
            return "NO MESSAGES";
        }
        else 
        // If the login hasn't been created yet
            return "NO MESSAGES";
    }


}

最佳答案

原因是您两次获取“NO MESSAGES”。
看一下 server.java

中的代码
 if (request.equals("READ")) {
   pw.println(protocol.messagesNumber());
   pw.println(protocol.readSender());
   pw.println(protocol.readMessage());
 }

这将调用 readSender()readMessage() 方法。

现在看一下这两个方法的返回语句 - return "NO MESSAGES";

只需在这两个方法中设置调试断点并进行调试和检查即可!

关于java - 输出被打印两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43165090/

相关文章:

c++ - Qt的QTcpSocket ReadyRead信号的实现

c - select()/poll() 是否适合 C 语言中的简单实时游戏服务器?

java - 为什么 maven-war-plugin 的行为与标准 maven 依赖解析机制不同

java - 如何确定 Selenium Grid 上的测试已完成

c++ - 在 C++ 中使用 zeromq 将序列化的 Mat 对象发送到另一台计算机

java - System.out.println 不工作(控制台可见)

java - System.err.println和System.out.println处理的区别

java - 如何在 Java 中从 Linux 打开 UNC 路径?

java - 如何在没有关联窗口的情况下使图像出现在屏幕上

java - Eclipse 控制台中没有输出,但其余方法有效