【问题标题】:Java Server / Client TroubleJava 服务器/客户端故障
【发布时间】:2015-03-24 16:35:14
【问题描述】:

所以这是我们得到的问题:

为您提供了以下用于简单客户端/服务器应用程序的应用层网络协议。

客户端可以将令牌(单词)发送到服务器,服务器将它们添加到内存中的全局令牌列表中。令牌列表具有 10 个不同令牌的容量。令牌应按字典顺序降序(反向)存储在令牌列表中。 共有三种类型的请求:SUBMIT、REMOVE 和 退出。

协议详解:

  • 客户端请求(从客户端发送到服务器的消息):提交令牌 服务器:如果令牌列表尚未满,则将令牌添加到令牌的全局列表中(如果列表没有 包含该令牌)或忽略它(如果相应的令牌已经在列表中)。在这两种情况下, 通过向客户端发送消息 OK 来响应。如果列表已满(包含 10 个标记),则响应 向客户端发送消息错误。 token 代表不包含空格的字符串,请参阅类 Scanner (Java API)。 令牌列表应随时按字典顺序降序排序。选择一个 表示令牌列表的适当数据结构。
  • 客户端请求:删除令牌 服务器:如果令牌列表包含令牌,则将其从令牌列表中删除并回复客户端 消息确定。否则,回复 ERROR。
  • 客户端请求:退出 服务器:结束与该客户端的连接。没有回应。

第一季度。为服务器创建一个(非企业、非 servlet)Java 类,该类可以通过以下方式与客户端交互 符合给定协议的 Internet。 这里不支持并发处理客户端,只支持顺序处理客户端(即 只有在与客户端的连接结束后,新客户端才能连接到服务器,依此类推)。 服务器应该只维护一个永远不会被服务器清空的全局令牌列表 除非通过 REMOVE 请求(即,不是每个连接客户端的新空令牌列表)。

这是我目前的尝试:

公共类服务器{

private Socket s;
private Scanner in;
private PrintWriter out;

public static void main(String[] args) throws IOException {
    ServerSocket server = new ServerSocket(6789);
    Server serverInstance = new Server();
    System.out.println("Server running. Waiting for a client to connect...");
    while(true) {
        serverInstance.s = server.accept();
        System.out.println("Client connected");
        serverInstance.run();
        System.out.println("Client disconnected. Waiting for a new client to connect...");
    }
}

public void run() {
    try {
        try {
            in = new Scanner(s.getInputStream());
            out = new PrintWriter(s.getOutputStream());
            doService(); // the actual service
        } finally {
            s.close();
        }
    } catch (IOException e) {
        System.err.println(e);
    }
}
public void doService() throws IOException {
    while(true) {
        if(!in.hasNext())
            return;
        String request = in.next();
        System.out.println("Request received: " + request);
        // (...) test for type of request here (not implemented)
        Request(request);
    }
}
public void Request(String request) {
    ArrayList<String> tokens = new ArrayList<String>(10);
    String amountStr = in.next();
    if(request.startsWith("SUBMIT")) {
        if(tokens.size() <= 10){
            out.println(tokens.add(amountStr)); //server response
            System.out.println( amountStr + " added to list");
        }
        else{System.out.println("Error");
        } 
    }
    else if(request.startsWith("REMOVE")) {
    out.println(tokens.remove(amountStr)); //server response
    System.out.println(amountStr + " removed from list");
    } 
    else if(request.equals("QUIT")){
    System.err.println("Program ended");
    }

    System.out.println(tokens);
    out.flush();
    }
}

公共类客户端{

public static void main(String[] args) throws IOException {
     Socket s = new Socket("localhost", 6789);
     InputStream instream = s.getInputStream();
     OutputStream outstream = s.getOutputStream();
     Scanner in = new Scanner(instream);
     PrintWriter out = new PrintWriter(outstream);
     String request = "SUBMIT hello \n";
     out.print(request);
     out.flush();
     String response = in.nextLine();
     System.out.println("Token: " + response);
     s.close();
    }

}

输出:

服务器正在运行。正在等待客户端连接...

客户端连接

收到的请求:提交

您好已添加到列表中

[你好]

客户端已断开连接。正在等待新的客户端连接...

客户端连接

收到的请求:提交

您已添加到列表中

[嗨]

客户端已断开连接。正在等待新的客户端连接...

所以我已经让服务器正常工作,客户端可以连接到它并向数组列表提交一个令牌,但是每次新客户端向列表中添加一个令牌时,它只是替换旧的而不是添加到数组中。 [hi] 代替 [hello] 而不是变成 [hello, hi]。

对于 REMOVE 和 QUIT 请求,我真的不知道如何让它们正常工作。

任何帮助将不胜感激。

【问题讨论】:

    标签: java arraylist


    【解决方案1】:

    在我看来,这是因为您在每次客户请求服务时声明一个新的ArrayList。你打电话给run,然后打电话给Request,每次都声明一个新的ArrayList

    PS:更改Request方法的名称,应以小写开头:request()

    【讨论】:

    • 忘了给您一个可能的解决方案:只需将您的ArrayList 声明为类变量,而不是将其声明为方法request 的本地变量
    • 谢谢,SUBMIT 和 REMOVE 现在运行良好。
    • 您知道如何让 QUIT 正常工作吗?
    • mmm... 使request 返回一个boolean,所以当收到QUIT 时它返回false。然后在doService 上设置您的while(true),如下所示:` boolean keep=true; while(keep) { if(!in.hasNext()) 返回;字符串请求 = in.next(); System.out.println("收到的请求:" + request); // (...) 在这里测试请求的类型(未实现) keep=Request(request); }` 理论上这将终止循环,让你的 doServicereturn 到 run() 并完成它。
    • @Dani 记得把它放在答案中,而不仅仅是在答案附近。
    猜你喜欢
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    相关资源
    最近更新 更多