繁体   English   中英

在没有DataOutputStream和Socket的情况下关闭CipherOutputStream

[英]Close CipherOutputStream without DataOutputStream & Socket

我正在与Cipher合作,在那里将连接保持在基础socketdataoutputstream 现在,根据CipherOutputStream文档,为了使最终块离开加密器,我们需要调用close() 因此,将它与try-with-resource一起使用也会关闭基础流,我不希望因为我需要它们进行进一步的操作。

那么,有没有什么方法或实现可以帮助我在没有数据dataoutputstreamsocket情况下关闭cipheroutputstream 我听说FilterOutputStream但是我不知道如何使用它们。

我的代码:

public class ClientHandler implements Runnable {
Socket msock;
DataInputStream dis;
DataOutputStream dos;
String ip;
private miniClientHandler(Socket msock) {
            this.msock = msock;
        }
@Override
public void run() {
    try {
        dis = new DataInputStream(msock.getInputStream());
        dos = new DataOutputStream(msock.getOutputStream());

        ip = msock.getInetAddress().getHostAddress();

        String msg = dis.readLine();
        System.out.println(msg);

        if (msg.equals("Download")) {

                    String file2dl = dis.readLine(); //2
                    File file = new File(sharedDirectory.toString() + "\\" + file2dl);
                    dos.writeLong(file.length()); //3+

                    //AES-128 bit key initialization.
                    byte[] keyvalue = "AES128BitPasswd".getBytes();
                    SecretKey key = new SecretKeySpec(keyvalue, "AES");

                    //Initialize the Cipher.
                    Cipher encCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                    encCipher.init(Cipher.ENCRYPT_MODE, key);

                    //Get the IV from cipher.
                    IvParameterSpec spec = null;
                    try {
                        spec = encCipher.getParameters().getParameterSpec(IvParameterSpec.class);
                    } catch (InvalidParameterSpecException ex) {
                        Logger.getLogger(PeersController.class.getName()).log(Level.SEVERE, null, ex);
                    }

                    byte[] iv = spec.getIV();

                    dos.write(iv, 0, iv.length); //4+

                    //Encryption Mechanism.
                    try (FileInputStream fis = new FileInputStream(file)) {
                        try (CipherOutputStream cos = new CipherOutputStream(dos, encCipher)) {
                            int read;
                            byte[] buffer = new byte[1024 * 1024];
                            while ((read = fis.read(buffer)) != -1) {
                                cos.write(buffer, 0, read); //5+ due to dos as underlying parameter of cos.
                            }
                        }
                    }

                    String message = dis.readLine();
                    System.out.println(message);
                    if (message.equals("Fetching Done")) {
                        System.out.println("Fetching Done!");
                    } else if (message.equals("Fetching Drop")) {
                        System.out.println("Fetching Denied!");
                    }
                }
            } catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
                System.out.println(e.getMessage());
            }
        }

    }


现在,由于cos被包装在try-with-resource中,当while循环结束时,它将关闭流和底层的dos流,这些流进一步包装了msock导致整个套接字关闭,而我剩余的代码无用。

剩余的代码:

    String message = dis.readLine();
    System.out.println(message);
    if (message.equals("Fetching Done")) {
        System.out.println("Fetching Done!");
     } else if (message.equals("Fetching Drop")) {
                 System.out.println("Fetching Denied!");
     }

我以某种方式设法通过@EJP建议自己解决问题,以通过update()doFinal()创建自己的Cipher对象。

码:

//Encryption Mechanism.
  try (FileInputStream fis = new FileInputStream(file)) {

       byte[] buffer = new byte[1024 * 1024];
       byte[] cipherBlock = new byte[encCipher.getOutputSize(buffer.length)];
       int cipherBytes;
       int read;
       while ((read = fis.read(buffer)) != -1) {
              cipherBytes = encCipher.update(buffer, 0, read, cipherBlock);
              dos.write(cipherBlock, 0, cipherBytes);
        }
        cipherBytes = encCipher.doFinal(cipherBlock, 0); //let out the last block out of the encryptor.
        dos.write(cipherBlock, 0, cipherBytes);
     } catch (ShortBufferException | IllegalBlockSizeException | BadPaddingException ex) {
              Logger.getLogger(PeersController.class.getName()).log(Level.SEVERE, null, ex);
       }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM