【问题标题】:how send multiple answer from client to server without close BufferedReader [duplicate]如何在不关闭 BufferedReader 的情况下从客户端向服务器发送多个答案 [重复]
【发布时间】:2015-12-30 20:13:15
【问题描述】:

首先对不起我的英语。 :-) 这是我在这里的第一篇文章。

我有应用程序,比如 torrent。我在一台计算机上运行它,但有 2 个或更多实例。我必须询问用户他想要什么文件,然后将此文件发送给客户。如果我希望它是主机到主机或多主机。 我的问题是:当我发送到目录中的客户端列表文件时,他选择其中一个并发送到服务器 nameFile。然后服务器将此文件发送给客户端。但是当我发送 listFile 时,我必须关闭 bufferedreader,因为 readline() 正在阻塞。但如果我关闭我没有连接。任何想法? 请提出任何建议。这是我的代码:

服务器:

public class Server extends Thread {

    private Socket s;
    int numerKlienta;
    String line;
    List<String> list = new ArrayList();

    private ServerSocket serverSocket;
    String nazwaPliku = "";
    PrintWriter outToClient;
    String text = "";
    String tmp = "";

    public Server(int port) throws Exception {

        serverSocket = new ServerSocket(port);
        while (true) {

            Socket clientSocket = serverSocket.accept();
            BufferedReader inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            outToClient = new PrintWriter(clientSocket.getOutputStream(), true);

            String path = "C:\\Users\\Ania\\Desktop";



            File directory = new File(path);

            File[] files = directory.listFiles();

            for (int j = 0; j < files.length; j++) {
                if (files[j].isFile()) {

                    text = files[j].getName();


                    outToClient.println(text);

                }

            }

            //outToClient.flush();
            outToClient.close();      //i must close beacuse in client when           i writeBytes its blocking next steps

            nazwaPliku = inFromClient.readLine();
            System.out.println(nazwaPliku);

            outToClient.close();
        }

    }


}

客户:

public class Client {




    public Client(String host, int port) throws Exception{

             s = new Socket(host, port);


             DataOutputStream   outToServer= new DataOutputStream(s.getOutputStream());

    BufferedReader inFromServer =
             new BufferedReader(new
             InputStreamReader(s.getInputStream())); 

    System.out.println("lista plików w katalogu : ");
    while ((( odpowiedz = inFromServer.readLine()) != null)){  


     System.out.println( odpowiedz);
    }

    //here is blocking and stop 



        System.out.println(" Jaki plik chcesz przesłać? podaj pełną nazwę");
        Scanner sc= new Scanner(System.in);
        String nazwaPliku=sc.next();
            outToServer.writeBytes(nazwaPliku);
        //saveFile(nazwaPliku);

    }

还有我的主要:

public class Main {

    public static void main(String[] args) throws Exception {

        Server serwer=null;
        System.out.println("Czy czy chcesz rozpocząc pracę jako serwer? (t/n)");
        Scanner sc = new Scanner(System.in);
        String odpowiedz = sc.next();
        if (odpowiedz.equals("t")) {

            System.out.println(" Na jakim porcie rozpocząc nasłuch?");
            sc = new Scanner(System.in);
            int portSerwera = sc.nextInt();
             serwer = new Server(portSerwera);
            //serwer.start();


        } 
        else{

            System.out.println("Czy chcesz rozpocząc połączenie z jakimś serwerem? (t/n)");
            sc = new Scanner(System.in);
            odpowiedz = sc.next();

            if (odpowiedz.equals("t")) {

                System.out.println("podaj numer portu do połączenia z serwerem");
                sc = new Scanner(System.in);
                int portKlienta = sc.nextInt();
                Client fc = new Client("localhost", portKlienta);

【问题讨论】:

  • 没有什么要求你关闭 TCP 流。只需发送一个特殊行,这意味着您已到达文件末尾。
  • @PeterLawrey 不可行。您必须选择不可能出现在任何文件中的行。您至少需要一个转义协议。
  • @EJP 没错,这就是我所说的特殊。您也可以使用根据定义无效的字符。使用不是有效文本的字节编码,或简单的转义序列,例如 '.'本身带有一个额外的“。”如果该行以'.'开头
  • 彼得劳里,谢谢,它正在工作。我发送特殊行“结束”:-)

标签: java bufferedreader


【解决方案1】:

您需要设计一个包含结构化消息的协议,而不仅仅是发送线路。客户端必须知道消息何时结束。

例如,您可以决定通过发送一个空行 (1) 来结束您的文件列表。

当客户端读取文件时,当它收到空行时,它知道列表已终止,现在由客户端发送它的选择。

使用分隔符是一种方法。另一种方法是发送“数据包”,其中每个数据包以数据包中预期的多个字节或字符开头。客户端因此知道它必须读取 N 个字节才能读取整个数据包,并且一旦数据包被读取,它应该发送它的选择,然后再读取另一个数据包 (2)。

(1) 和 (2):请注意,您可能最常使用的协议会使用这两种策略:HTTP。 HTTP 响应的标头以空行结束。它通常包含响应正文的内容长度。

【讨论】:

  • 感谢您的快速回答。现在我看到我的错误。它不是 bufferedReader 我必须关闭,但我关闭了 PrintWriter。
  • @Ania.K 所以不要关闭 PrintWriter,只需在发送终止字符串后刷新它。理想情况下,您会在套接字连接的整个生命周期中使用相同的包装器。
  • 如果我只是冲洗不起作用。它正在阻塞。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-20
  • 1970-01-01
  • 2019-12-24
  • 2016-02-28
  • 2021-08-10
相关资源
最近更新 更多