简体   繁体   English

从套接字读取/解密时发生java.io.EOFException

[英]java.io.EOFException when read/decrypt from a socket

I have a big client-server program. 我有一个很大的客户端服务器程序。

But if I send a crypted package, when trying to receive and decrypt it, causes an java.io.EOFException . 但是,如果我发送一个加密的程序包,则在尝试接收和解密它时会导致java.io.EOFException

If I use the non encrypted way (for instance for pings) it works perfectly. 如果我使用非加密方式(例如ping),则可以正常工作。

Client code (receive): 客户端代码 (接收):

InputStream is = subChannel.getInputStream();
ObjectInputStream pre = new ObjectInputStream(is);
ObjectInputStream ois;
boolean crypt = (boolean) pre.readObject();

if (crypt) {
    ois = new ObjectInputStream(SimpleAES.decryptInputStream(c.getAesKey(), is));
} else {
    ois = new ObjectInputStream(is);
}

Response<? extends Serializable> res = (Response<? extends Serializable>) ois.readObject();
req.onResponse(res);
is.close();

subChannel is a Socket which connects seperated. subChannel是一个单独连接的套接字。

I know that I get a response this can't be the error. 我知道我得到了答复,这不可能是错误。

SimpleAES SimpleAES

private final static byte[] iv = new byte[16];
private static final String TRANSFORMATION = "AES/CBC/NoPadding";

public static CipherOutputStream cryptOutputStream(SecretKey key,OutputStream os) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        IvParameterSpec ivspec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, ivspec);
        CipherOutputStream out = new CipherOutputStream(os, cipher);
        return out;
}

public static CipherInputStream decryptInputStream(SecretKey key,InputStream os) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        IvParameterSpec ivspec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, key, ivspec);
        CipherInputStream out = new CipherInputStream(os, cipher);
        return out;
}

Server code (sending): 服务器代码 (发送):

OutputStream base;
base = sock.getOutputStream();

ObjectOutputStream infoStream = new ObjectOutputStream(base);

infoStream.writeObject(pack.isEncrypted());
ObjectOutputStream packageStream;

if (pack.isEncrypted()) {
    String tolken = pack.getClientTolken();
    Session s = getSession(tolken);
    packageStream = new ObjectOutputStream(SimpleAES.cryptOutputStream(s.getAesKey(), base));
}
else
    packageStream = new ObjectOutputStream(base);

packageStream.writeObject(pack);
packageStream.flush();

if (pack instanceof Request) {
    InputStream baseIn = sock.getInputStream();
    ObjectInputStream res;

    if (pack.isEncrypted()) {
        res = new ObjectInputStream(SimpleAES.decryptInputStream(getSession(pack.getClientTolken()).getAesKey(), baseIn));
    } else {
        res = new ObjectInputStream(baseIn);
    }

    @SuppressWarnings("unchecked")
    Response<? extends Serializable> response = (Response<? extends Serializable>) res.readObject();
    ((Request) pack).onResponse(response);
    res.close();
}

base.close();

I don't think the stack trace will give you big information but here it is: 我认为堆栈跟踪不会为您提供大量信息,但是它是:

Ping Response : 8ms
[Client] Added TolkenRequest to Query
[Client] Added RSARequest to Query
[Client] Added AESKeyPack to Query
[Client] Added ValidIdRequest to Query
java.io.EOFException
Fatal Error Exit
    at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
    at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
    at java.io.ObjectInputStream.readShort(Unknown Source)
    at java.io.ObjectStreamClass.readNonProxy(Unknown Source)
    at java.io.ObjectInputStream.readClassDescriptor(Unknown Source)
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at com.niton.tele.core.network.client.ClientListenerThread.run(ClientListenerThread.java:104)

ClientListenerThread.java:104 is this line Response res = (Response) ois.readObject(); ClientListenerThread.java:104是这一行Response res =(Response)ois.readObject();

You can't mix different buffered streams on the same socket. 您不能在同一套接字上混合使用不同的缓冲流。 They will steal data from each other. 他们将互相窃取数据。 You need to redesign and rewrite this using a single ObjectInputStream and ObjectOutputStream for the life of the socket. 您需要在套接字的生命周期内使用单个ObjectInputStreamObjectOutputStream重新设计并重写它。

Possibly you are looking for SealedObject ? 可能您正在寻找SealedObject

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

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