当前位置: 首页 > 知识库问答 >
问题:

如何在Java的客户端-服务器应用程序中读写多行

束研
2023-03-14

我有一个多线程的Java客户端-服务器应用程序,发现自己与多线程通信的斗争。这是我的意思

如果我这样写一个服务器

private static void startHandler(final Socket socket)
    {
        Thread thread = new Thread()
        {
            @Override
            public void run()
            {
                try {
                    Scanner inputFromUser = new Scanner(socket.getInputStream());
                    PrintStream outPutToUser = new PrintStream(socket.getOutputStream(), true);
                    outPutToUser.println("Welcome!");
                    System.out.println(inputFromUser.nextLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        thread.start();

    }

并这样编写客户端:

public static void main(String[] args) throws Exception
    {
        Scanner inputFromUser = new Scanner(System.in);
        Socket socket = new Socket("127.0.0.1", 5555);
        Scanner inputFromServer = new Scanner(socket.getInputStream());
        PrintStream outputToServer = new PrintStream(socket.getOutputStream());
        String greetingFromServer = inputFromServer.nextLine();
        System.out.println(greetingFromServer);
        outputToServer.println(inputFromUser.nextLine());
    }

它运作得很好:

>

  • 服务器向客户端发送“欢迎”

    用户输入一些字符串

    在服务器控制台中打印该字符串

    但如果我试图让它变得更复杂,就像这样:

    private static void startHandler(final Socket socket)
        {
            Thread thread = new Thread()
            {
                @Override
                public void run()
                {
                    try {
                        Scanner inputFromUser = new Scanner(socket.getInputStream());
                        PrintStream outPutToUser = new PrintStream(socket.getOutputStream(), true);
                        outPutToUser.println("Welcome!");
                        sendInitialCommandsToUser(outPutToUser);
                        System.out.println(inputFromUser.nextLine());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            thread.start();
    
        }
    
        private static void sendInitialCommandsToUser(PrintStream writer)
        {
            writer.println("1 - Log In");
            writer.println("2 - Sign up");
            writer.println("3 - Exit");
        }
    

    客户:

    public static void main(String[] args) throws Exception
        {
            Scanner inputFromUser = new Scanner(System.in);
    
            Socket socket = new Socket("127.0.0.1", 5555);
            Scanner inputFromServer = new Scanner(socket.getInputStream());
            PrintStream outputToServer = new PrintStream(socket.getOutputStream());
    
            String greetingFromServer = inputFromServer.nextLine();
            System.out.println(greetingFromServer);
    
            getMultipleLinesFromServer(inputFromServer);
    
            outputToServer.println(inputFromUser.nextLine());
        }
    
        private static void getMultipleLinesFromServer(Scanner scanner)
        {
            while(scanner.hasNextLine())
            {
                System.out.println(scanner.nextLine());
            }
        }
    

    它被堆放在GetMultipleLinesFromServer(Scanner Scanner)方法上

    客户端输出仅

    Welcome!
    1 - Log In
    2 - Sign up
    3 - Exit
    

    我无法提供要在服务器上打印的字符串..有什么问题?

  • 共有2个答案

    姚星腾
    2023-03-14

    如果您查看扫描器hasNextLine方法的Javadocs...

     Returns true if there is another line in the input of this scanner.
     This method may block while waiting for input. The scanner does not
     advance past any input.
    

    似乎一旦它打印了“3-exit”,它就会阻塞以等待来自服务器的更多数据。

    阴阳
    2023-03-14

    如果希望按行读取,BufferedReader是一个不错的选择

    试试这个,对我的主意很管用

    package com.zhouplus;
    
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class Server {
    
        private static void startHandler(final Socket socket) {
            Thread thread = new Thread(() -> {
                try {
                    BufferedReader inputFromUser = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    PrintWriter outPutToUser = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
                    outPutToUser.println("Welcome!");
                    sendInitialCommandsToUser(outPutToUser);
                    System.out.println("start readline!");
                    System.out.println(inputFromUser.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            thread.start();
        }
    
        private static void sendInitialCommandsToUser(PrintWriter writer) {
            writer.println("1 - Log In");
            writer.println("2 - Sign up");
            writer.println("3 - Exit");
            writer.flush();
        }
    
        public static void main(String[] argv) throws IOException {
            ServerSocket ss = new ServerSocket(5555);
            Socket accept = ss.accept();
            startHandler(accept);
        }
    }
    

    和客户端

    package com.zhouplus;
    
    import java.io.*;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class Client {
        public static void main(String[] args) throws Exception {
            Scanner inputFromUser = new Scanner(System.in);
    
            Socket socket = new Socket("localhost", 5555);
            BufferedReader inputFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter outputToServer = new PrintWriter(socket.getOutputStream());
    
    
            String greetingFromServer = inputFromServer.readLine();
            System.out.println(greetingFromServer);
    
            new Thread(() -> {
                String str = inputFromUser.nextLine();
                outputToServer.println(str);
                outputToServer.flush();
            }).start();
    
            getMultipleLinesFromServer(inputFromServer);
        }
    
        private static void getMultipleLinesFromServer(BufferedReader br) throws IOException {
            String str;
            while ((str = br.readLine()) != null) {
                System.out.println(str);
            }
            System.out.println("over");
        }
    }
    
     类似资料:
    • 我是Java的新手,我正在尝试学习线程和套接字。所以决定按照官方的java教程制作简单的客户机-服务器应用程序。我的想法很简单--服务器等待连接,如果出现,它就用新的套接字、输入和输出生成新线程。客户端->建立连接;带有套接字、输入、输出和stdIn的新线程(读取行,然后发送到服务器)。但是我的代码出了点问题(不知道为什么)。连接已经建立,没有例外。谁能解释一下为什么不工作,如何修复它?您还可以对

    • 问题内容: 我正在尝试以客户端/服务器方式制作Java应用程序。客户端是SWT中的GUI,它显示来自服务器的数据。服务器已连接到数据库。 好的,对此感到抱歉,我确定这是一个经典问题,但我不知道如何开始。 在我为他们工作的一个项目中,他们实施了很多魔术来透明地调用Glassfish服务器。 我不想使用Glassfish服务器。我只想要简单的Java语言。但是代理的概念似乎很酷。 你有这种想法或例子吗

    • 问题内容: 我正在尝试使用我一直在努力的客户端/服务器程序实现多线程。我需要允许多个客户端同时连接到服务器。我目前有4类:客户端,服务器,协议和用于处理线程的工作器。以下代码是我对这些类的拥有的代码: SocketServer类: SocketClient类别: 协议类别: ClientWorker类: 当我运行服务器和客户端时,一切正常。然后,当我尝试运行另一个客户端时,它只是挂在那儿,没有提示

    • 问题内容: 我正在编写一个Java包,该包将由另一种语言(matlab)调用。如果我的matlab进程结束,我希望Java进程继续运行。每当MATLAB重新启动时,它都应该能够与现有的运行过程进行通信。因此,我认为我需要让Java应用程序通过客户端/服务器模型中的套接字进行通信。我设想具有一组简单的功能: startServer(主机,端口) runCommand(服务器,命令…) stopSer

    • 我想同步2个集合。如果服务器端有什么变化,连接的客户端就会更新。我有一个非常基本的问题。我现在需要复制我的java项目,并在一个项目中编程服务器,在另一个项目中编程客户端吗?但这听起来像是相当多不必要的工作。我不能在一个项目中实现这一切,然后在一个主项目中启动服务器和客户端吗?我需要线程吗?我有点纠结于最好的方法是什么。提前谢谢。