0

尝试编写客户端/服务器程序,其中客户端读取文本文件并使用 CipherOutputStream 将其发送到服务器套接字。预期的文本文件已创建但为空,并且出现以下错误

读取长度-1

EOF:空

我有这个方法encrypt() 进行加密然后发送数据

private static void encrypt(InputStream is, OutputStream os) {

    try {

        byte[] buf = new byte[1024];

// 此流中的字节首先被编码

        os = new CipherOutputStream(os, ecipher);

// 读入明文并写出以加密

        int numRead = 0;

        while ((numRead = is.read(buf)) >= 0) {

            os.write(buf, 0, numRead);

        }

// 关闭所有流

        os.close();

    } catch (IOException e) {

        System.out.println("I/O Error:" + e.getMessage());

    }

}

下面是客户端的大部分代码

public void actionPerformed(ActionEvent e) {

    //Handle open button action.
    if (e.getSource() == openButton) {
        int returnVal = fc.showOpenDialog(FileChooserDemo.this);

        if (returnVal == JFileChooser.APPROVE_OPTION) {
            try {
                SecretKey key = KeyGenerator.getInstance("DES").generateKey();

                AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);

                ecipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

                dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

                ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);

                dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);

                File file = fc.getSelectedFile();

                Socket s = null;
                s = new Socket("localhost", 6880);
                DataOutputStream output = new DataOutputStream(s.getOutputStream());


                encrypt(new FileInputStream(file), output);

                log.append("encrypted " + newline);

                log.append("Sent" + file.getName() + "." + newline);
            } catch (Exception ex) {
                Logger.getLogger(FileChooserDemo.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            log.append("Open command cancelled by user." + newline);
        }
        log.setCaretPosition(log.getDocument().getLength());

        //Handle save button action.
    } else if (e.getSource() == saveButton) {
        int returnVal = fc.showSaveDialog(FileChooserDemo.this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            //This is where a real application would save the file.
            log.append("Saving: " + file.getName() + "." + newline);
        } else {
            log.append("Save command cancelled by user." + newline);
        }
        log.setCaretPosition(log.getDocument().getLength());
    }
}

然后侦听服务器使用 CipherInputStream 读取数据,然后将其写入文本文件。服务器包含以下内容

private static void decrypt(InputStream is, OutputStream os) {

    try {

        byte[] buf = new byte[1024];

// 从流中读取的字节将被解密

        CipherInputStream cis = new CipherInputStream(is, dcipher);

// 读入解密字节并将明文写入 out

        int numRead = 0;

        while ((numRead = cis.read(buf)) >= 0) {

            os.write(buf, 0, numRead);

        }

// 关闭所有流

        cis.close();

        is.close();

        os.close();

    } catch (IOException e) {

        System.out.println("I/O Error:" + e.getMessage());

    }

}

public void run() {
    try {

        SecretKey key = KeyGenerator.getInstance("DES").generateKey();

        AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);


        dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

        dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);

        decrypt(input, new FileOutputStream("cleartext-reversed.txt"));

        FileWriter out = new FileWriter("test.txt");
        BufferedWriter bufWriter = new BufferedWriter(out);


        System.out.println("receive from : "
                + clientSocket.getInetAddress() + ":"
                + clientSocket.getPort());
        //Step 1 read length
        int nb = input.read();
        System.out.println("Read Length" + nb);

        String enctext = Character.toString(input.readChar());
        Integer.toString(nb);
        //Step 2 read byte

        String st = new String("see if it can write");
        bufWriter.append(enctext);
        bufWriter.close();


        //Step 1 send length
        output.writeInt(st.length());
        //Step 2 send length
        output.writeBytes(st); // UTF is a string encoding
        //  output.writeUTF(data);
    } catch (NoSuchPaddingException ex) {
        Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidAlgorithmParameterException ex) {
        Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
    } catch (EOFException e) {
        System.out.println("EOF:" + e.getMessage());
    } catch (IOException e) {
        System.out.println("IO:" + e.getMessage());
    } finally {
        try {
            clientSocket.close();
        } catch (IOException e) {/*close failed*/

        }
    }
}
4

1 回答 1

1

服务器执行以下操作:

decrypt(input, new FileOutputStream("cleartext-reversed.txt"));

它从输入流中读取所有内容,对其进行解密,并将结果写入文本文件并关闭输入流。

然后,你正在尝试做

int nb = input.read();
...
input.readChar()

因此,它尝试从刚刚完全读取并关闭的输入流中再次读取。

注意:如果不是隐藏异常,诊断会容易得多

System.out.println("EOF:" + e.getMessage());

你做了

e.printStackTrace();

这会告诉你它是什么异常,以及它发生在哪里。

于 2013-08-24T21:13:27.330 回答