首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DataOutputStream只发送关闭

DataOutputStream只发送关闭
EN

Stack Overflow用户
提问于 2018-04-12 18:45:47
回答 1查看 98关注 0票数 0

当我在没有close方法的情况下运行此代码时,服务器无法接收消息!

客户:

代码语言:javascript
复制
        Socket con = new Socket(InetAddress.getByName("localhost"), 12345);

        InputStream is = con.getInputStream();
        OutputStream os = con.getOutputStream();

        byte[] key = new byte[]{5};

        DataOutputStream dos = EncryptIO.getEncryptedOutputStream(key, os);
        DataInputStream dis = EncryptIO.getEncryptedInputStream(key, is);

        dos.writeUTF("Player 2");
        dos.close(); //with this the server receives the message
        String opUsername = dis.readUTF();

服务器:

代码语言:javascript
复制
        ServerSocket serverSocket = new ServerSocket(12345);
        Socket con = serverSocket.accept();

        InputStream is = con.getInputStream();
        OutputStream os = con.getOutputStream();

        byte[] key = new byte[]{5};

        DataOutputStream dos = EncryptIO.getEncryptedOutputStream(key, os);
        DataInputStream dis = EncryptIO.getEncryptedInputStream(key, is);

        String opUsername = dis.readUTF();
        System.out.println(opUsername);

        dos.writeUTF("Player 1"); //this line isn't reached because DataInputStream waits for the data

在DataOutput/InputStream下面是底层的密码流,而没有,它可以工作!

EncryptIO代码:

代码语言:javascript
复制
public static DataInputStream getEncryptedInputStream(byte[] key, InputStream is) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchPaddingException {
    try {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, EncryptIO.getAESKey(key), EncryptIO.getIV(key));
        CipherInputStream cis = new CipherInputStream(is, cipher);
        return new DataInputStream(cis);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(EncryptIO.class.getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

public static DataOutputStream getEncryptedOutputStream(byte[] key, OutputStream os) throws InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException {
    try {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, EncryptIO.getAESKey(key), EncryptIO.getIV(key));
        CipherOutputStream cos = new CipherOutputStream(os, cipher);
        return new DataOutputStream(cos);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(EncryptIO.class.getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

如何才能让DataOutputStream发送加密和不关闭的数据?

提前感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-12 19:55:13

从…

代码语言:javascript
复制
Cipher.getInstance("AES/CBC/PKCS5Padding")

您正在用PKCS5Padding在CBC模式下使用AES密码。根据JDK 8的Java密码体系结构标准算法名称文档 (重新格式化,并按原始链接):

AES NIST在FIPS 197中指定的高级加密标准。AES也被琼·戴门和文森特·里伊门称为Rijndael算法,是一种128位、192位和256位的支持密钥的128位分组密码。 若要使用只有一个有效密钥大小的AES密码,请使用格式AES_,其中可以是128、192或256。

CBC 密码块链接模式,如FIPS酒吧81中定义的。

PKCS5Padding RSA实验室,"PKCS #5:基于密码的加密标准“,版本1.5,1993年11月中描述的填充方案。

因此,一个块密码,可能在128位(16字节),与填充。

请注意,这来自密码算法模式

循环流化床,CFBx 密码反馈模式,如FIPS酒吧81中定义的。 使用CFB和OFB等模式,块密码器可以以比密码的实际块大小更小的单位加密数据。当请求这样的模式时,您可以选择一次指定要处理的位数,方法是将这个数字附加到模式名称中,如“DES/CFB8 8/NoPadding”和“DES/ of 32/PKCS5Padd”转换中所示。如果未指定此数字,则使用特定于提供程序的默认设置。(例如,SunJCE提供程序对DES使用64位的缺省值。)因此,通过使用8位模式(如CFB8或OFB8 ),块密码可以转换为面向字节的流密码。

因此,"AES/CFB8/NoPadding"或类似的应该作为一个非阻塞流密码工作。但是,您可能仍然必须对流进行flush()。而且很可能会对业绩产生影响。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49803866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档