Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java DataOutputStream仅在关闭时发送_Java - Fatal编程技术网

Java DataOutputStream仅在关闭时发送

Java DataOutputStream仅在关闭时发送,java,Java,当我在没有close方法的情况下运行此代码时,服务器无法接收消息 客户: Socket con = new Socket(InetAddress.getByName("localhost"), 12345); InputStream is = con.getInputStream(); OutputStream os = con.getOutputStream(); byte[] key = new byte[]{5};

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

客户:

        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();
服务器:

        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下面是下面的密码流,没有它们它就可以工作

加密代码:

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在不关闭的情况下通过加密发送数据

提前感谢

来自

Cipher.getInstance("AES/CBC/PKCS5Padding")
您正在CBC模式下与PKCS5P一起使用AES密码。根据(重新格式化,每个原始链接):

AES

NIST在年规定的高级加密标准。 Joan Daemen和Vincent也称为Rijndael算法 AES是一种128位的分组密码,支持128、192和128个密钥 256位

要仅使用一个有效密钥大小的AES密码,请使用以下格式 其中可以是128、192或256

CBC

密码块链接模式,如中所定义

PKCS5Padding

中描述的填充方案

因此,一个可能是128位(16字节)的分组密码,带有填充

请从密码算法模式中注意:

CFB,CFBx

密码反馈模式,如中所定义

使用CFB和OFB等模式,分组密码可以对数据库中的数据进行加密 小于密码实际块大小的单位。请求时 在这种模式下,您可以选择指定要使用的位数 通过将此编号附加到模式名称,一次处理一次,如图所示 在“DES/CFB8/NoPadding”和“DES/OFB32/PKCS5Padding”中 转变。如果未指定此类号码,则指定特定于提供商的号码 使用默认值。(例如,SunJCE提供程序使用默认值 因此,块密码可以转换为面向字节的密码 使用8位模式(如CFB8或OFB8)的流密码

因此,
“AES/CFB8/NoPadding”
或类似密码应作为非阻塞流密码使用。但是,您可能仍然需要
flush()
流。而且可能会对性能产生影响。

来自

Cipher.getInstance("AES/CBC/PKCS5Padding")
您正在CBC模式下与PKCS5P一起使用AES密码。根据(重新格式化,每个原始链接):

AES

NIST在年规定的高级加密标准。 Joan Daemen和Vincent也称为Rijndael算法 AES是一种128位的分组密码,支持128、192和128个密钥 256位

要仅使用一个有效密钥大小的AES密码,请使用以下格式 其中可以是128、192或256

CBC

密码块链接模式,如中所定义

PKCS5Padding

中描述的填充方案

因此,一个可能是128位(16字节)的分组密码,带有填充

请从密码算法模式中注意:

CFB,CFBx

密码反馈模式,如中所定义

使用CFB和OFB等模式,分组密码可以对数据库中的数据进行加密 小于密码实际块大小的单位。请求时 在这种模式下,您可以选择指定要使用的位数 通过将此编号附加到模式名称,一次处理一次,如图所示 在“DES/CFB8/NoPadding”和“DES/OFB32/PKCS5Padding”中 转变。如果未指定此类号码,则指定特定于提供商的号码 使用默认值。(例如,SunJCE提供程序使用默认值 因此,块密码可以转换为面向字节的密码 使用8位模式(如CFB8或OFB8)的流密码


因此,
“AES/CFB8/NoPadding”
或类似密码应作为非阻塞流密码使用。但是,您可能仍然需要
flush()
流。这可能会对性能造成影响。

如果您的意思是抱歉,我的评论不完整,我不是有意发布它,我会直接尝试刷新操作系统。是的,我要说的是,即使DataOutputStream没有缓冲区,父流
os
也可能有缓冲区,在CipherOutputStream的情况下也有缓冲区,因此需要刷新它。我会尝试刷新dos,它会刷新所有的父流。你说的如何让它与加密一起工作是什么意思?什么不起作用?我不是说直接操作系统,但是dos@AndrewHenle正如我所说:发送数据我试图直接刷新操作系统,如果你的意思是抱歉,我的评论不完整,我不想发布它。是的,我要说的是,即使DataOutputStream没有缓冲区,父流
os
也可能有缓冲区,在CipherOutputStream的情况下也有缓冲区,因此需要刷新它。我会尝试刷新dos,它会刷新所有的父流。你说的如何让它与加密一起工作是什么意思?什么不起作用?我不是说直接操作系统,但是dos@AndrewHenle正如我所说:发送数据谢谢,我从来没有想到这是密码的问题。谢谢你结构化的回答谢谢,我从没想过这是密码的问题。谢谢你有条理的回答