输入流中丢失的字节数为

时间:2018-05-07 03:17:07

标签: java sockets inputstream public-key

我正在编写一个程序,我从输出套接字创建的密钥对中发送密钥的字节,并使用它们在另一端重新创建密钥。 服务器:

    KeyPairGenerator dsaKeyPairGenerator = 
    KeyPairGenerator.getInstance("DSA");
    dsaKeyPairGenerator.initialize(1024);
    KeyPair dsakeyPair = dsaKeyPairGenerator.generateKeyPair();
    PrivateKey dsaPrivate = dsakeyPair.getPrivate();
    PublicKey dsaPublic = dsakeyPair.getPublic();
    byte[] dsaPublicbytes = dsaPublic.getEncoded();
    clientSocket.getOutputStream().write(dsaPublicbytes.length);
    clientSocket.getOutputStream().write(dsaPublicbytes);

客户:

    int dsalength = clientSocket.getInputStream().read();
    byte[] dsaPublicbytes = new byte[dsalength];
    clientSocket.getInputStream().read(dsaPublicbytes);
    X509EncodedKeySpec dsaspec = new X509EncodedKeySpec(dsaPublicbytes);
    KeyFactory dsakeyFactory = KeyFactory.getInstance("DSA");
    PublicKey dsaKey = dsakeyFactory.generatePublic(dsaspec);

然而,在这一行我收到一个错误:

    PublicKey dsaKey = dsakeyFactory.generatePublic(dsaspec);

错误本身的跟踪:

Exception in thread "main" java.security.spec.InvalidKeySpecException: Inappropriate key specification: IOException: Detect premature EOF
at sun.security.provider.DSAKeyFactory.engineGeneratePublic(DSAKeyFactory.java:119)
at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
at Client.main(Client.java:36)

我已经研究过并且我已经看到EOF发生了,因为没有足够的字节来创建密钥,这让我相信它是如何发送字节的问题。我是否错误地发送了字节?

2 个答案:

答案 0 :(得分:1)

  

输入流中丢失的字节

输入流中的

未读字节。您假设read()填充了缓冲区。它没有义务这样做。使用DataInputStream.readFully()

您还可以使用write(int)read()无参数限制自己使用128个关键字节来发送/接收长度字。请使用DataOutputStream.writeInt()DataInputStream.readInt()

答案 1 :(得分:0)

假设您的第一个字节没有发送关键字节数组的大小,或者您使用的是大小超过256位的密钥,那么该数组将不完整。 尝试使用writeLong()或writeInt()的DataOutputStream方法发送字节大小以启动正确大小的数组。其次尝试使用缓冲区来读取它的发送时间。

以下是我的文件套接字发送者的一些代码: 这是发送部分:

    OutputStream os = sock.getOutputStream();
    DataOutputStream dos = new DataOutputStream(os);     
    dos.writeInt(mybytearray.length);   
    dos.write(mybytearray, 0, mybytearray.length);   

这是收到的部分:

InputStream in = sock.getInputStream();
DataInputStream dis = new DataInputStream(in);
int byteSize = clientData.readInt();
byte[] byteData = new Byte[byteSize];
dis.read(byteData);

您可能希望通过使用DIS read(byte[],int,int)的方法告知要读取多少字节来缓冲接收部分,直到读取所有字节为止。我在同一台计算机上使用非常小的数据测试了我的代码,因此连接稳定性不是一个因素。