当前位置: 首页 > 面试题库 >

为什么InputStream.read()在这里阻塞?

姜晨
2023-03-14
问题内容

我应该开发一个简单的SFTP。
一切都进行得很好,直到我ByteArrayOutputStream(在本例中baos)没有编写全部为止arrayByte。可以请我解释一下,为什么系统挂在我身上吗?

服务器端:

public static void main (String[] args)
{
        int portTexto = 5656;
        String comando;
        String regexGet = "\\s*(get)\\s[A-z0-9]*\\.[A-z0-9]*\\s*";
        String regexPut = "\\s*(put)\\s[A-z0-9]*\\.[A-z0-9]*\\s*";

        try{

            ServerSocket servSockTexto = new ServerSocket(portTexto);

            // pegar IP de servidor.
            try {
                  InetAddress addr = InetAddress.getLocalHost();            
                  System.out.println(addr.getHostAddress());
            } 
            catch (UnknownHostException e) {
            }

            System.out.println("Aguardando conexão com Servidor de Texto...");
            Socket sock = servSockTexto.accept(); 
            System.out.println("Conexão com Servidor estabelecida.");

            //BufferedOutputStream paraCliente = new BufferedOutputStream(sock.getOutputStream());

            DataInputStream inputServ = new DataInputStream(sock.getInputStream());
            DataOutputStream outputServ = new DataOutputStream(sock.getOutputStream());

            BufferedOutputStream paraCliente = new BufferedOutputStream(sock.getOutputStream());

            //1
            outputServ.writeUTF("Conexão com Servidor estabelecida.");

            do
            {

                //3
                comando = inputServ.readUTF();

                if(comando.matches(regexGet))
                {

                    String[] aux = comando.split("\\s");
                    String nomeArq = aux[1];

                    File arqGet = new File(nomeArq);

                    //4
                    outputServ.writeUTF(arqGet.getName());

                    byte[] arrayByte = new byte[(int) arqGet.length()];


                    FileInputStream fInput = new FileInputStream(arqGet);
                    BufferedInputStream bInput = new BufferedInputStream(fInput);

                    bInput.read(arrayByte, 0, arrayByte.length);

                    //5
                    paraCliente.write(arrayByte.length);

                    //6
                    paraCliente.write(arrayByte, 0, arrayByte.length);

                    paraCliente.flush();
                    bInput.close();
                    fInput.close();

                }
                else if(comando.matches(regexPut))
                {

                }
                else if (!comando.equals("sair"))
                {
                    //4
                    outputServ.writeUTF("Comando não existente.");
                }

            }
            while(!comando.equals("sair"));

            servSockTexto.close();
            sock.close();
            inputServ.close();
            outputServ.close();
            paraCliente.close();

        }
        catch (Exception ex)
        {
            System.out.println("Erro: " + ex);
        }

    }

客户端:

    public static void main (String[] args)
    {
        String IP = "localhost";
        String comando;
        String regexGet = "\\s*(get)\\s[A-z0-9]*\\.[A-z0-9]*\\s*";
        String regexPut = "\\s*(put)\\s[A-z0-9]*\\.[A-z0-9]*\\s*";
        int portTexto = 5656;
        Scanner scan = new Scanner(System.in);


        try{

            Socket sock = new Socket (IP,portTexto);

            //BufferedInputStream is = new BufferedInputStream(sock.getInputStream());

            DataInputStream inputCli = new DataInputStream(sock.getInputStream());
            DataOutputStream outputCli = new DataOutputStream(sock.getOutputStream());

            InputStream is = sock.getInputStream();
            //BufferedInputStream is = new BufferedInputStream(sock.getInputStream());

            //1
            System.out.println(inputCli.readUTF());


            do
            {
                System.out.println("Digite um comando:");
                comando = scan.nextLine();

                //3
                outputCli.writeUTF(comando);

                if(comando.matches(regexGet))
                {

                    //4
                    String arqTeste = "C:\\Users\\Frederico\\Desktop\\Download SFTP\\" + inputCli.readUTF();


                    int bytesRead;


        ByteArrayOutputStream baos = new      ByteArrayOutputStream();                         FileOutputStream fos = new FileOutputStream( arqTeste );
                  BufferedOutputStream bos = new BufferedOutputStream(fos);

                    //5
                    byte[] aByte = new byte[1];


                    //6
                    bytesRead = is.read(aByte, 0, aByte.length);



                     // MY SYSTEM STAYS INSIDE THIS DO AND I CANT SOLVE THIS!!!  
                    do 
                    {
                            baos.write(aByte);
                            bytesRead = is.read(aByte);

                    } 
                    while (bytesRead != -1);


                    //is.close();
                    bos.write(baos.toByteArray());
                    bos.flush();
                    bos.close();


                }
                else if(comando.matches(regexPut))
                {}
                else if (!comando.equals("sair"))
                {
                    //4
                    System.out.println(inputCli.readUTF());
                }


            }
            while(!comando.equals("sair"));

            is.close();
            sock.close();
            inputCli.close();
            outputCli.close();

            System.out.println("Conexão com servidor encerrada.");

        }
        catch (Exception ex)
        {
            System.out.println("Erro: " + ex);
        }

    }

问题答案:

您的do/while循环一直运行到流结束,但是对等方永远不会关闭套接字。该协议似乎要求打开套接字以供其他命令使用,因此您必须调整它的这一部分以包括一个长度字前缀,以便您知道要复制多少字节。

问题不是关于ByteArrayOutputStream不写所有字节,而是关于阻塞in is.read()



 类似资料:
  • 测试代码为: 测试代码为: 你知道怎么了吗?

  • 我遇到JSON解析错误。我的代码如下: 我从我的检查中得到以下错误: 由于:com,无法分析JSON。谷歌。格森。JsonSyntaxException:java。lang.IllegalStateException:应为BEGIN\u对象,但在第1行第2列为BEGIN\u数组 对于我试图读取的JSON,如果成功,我的应该返回5。 我做错了什么?

  • 这是我的线程: 它得到一个上限和下限以及一个在所有线程上共享的结果。 这是我的测试类:

  • 问题内容: 我刚读 ISO / IEC 9899:201x委员会草案-2011年4月12日 在其中我发现5.1.2.2.3程序终止 这表示如果您未在中指定任何return语句,并且如果程序成功运行,则main的右大括号}将返回0。 但是在下面的代码中,我没有指定任何return语句,但是它没有返回0 编译 问题答案: 该规则是在C标准的1999版本中添加的。在C90中,返回的状态未定义。 您可以通

  • 问题内容: 我正在尝试通过以下方式将日期范围划分为各个日期: 而且我不知道为什么不起作用,因为日期仍然相同,所以循环变得无限。 问题答案: plusDays不会改变原始的,您必须分配结果:

  • 我有以下方法调用层次结构 在上面的场景中,我的期望是Spring应该在线程从Method od1出来时提交事务,或者如果在层次结构中的任何位置发生异常,则回滚。 但是Spring在方法2中执行更新后立即提交事务。我不明白为什么? 更新:-即使我将事务更改为事务(传播=传播。需要\u NEW),它仍会提交事务。所以没有影响