0

我正在尝试将 Key 类型的公钥对象发送到我的服务器。但我没有得到这个运行。prototocl 如下所示:

[命令]\n[序列化密钥对象]

客户端使用此代码:

Socket admin;
PrintWriter pw;
OutputStream os;
BufferedReader is; 
for(int tries = 0; tries < MAX_RECONNECT_TRIES_ADMIN_SERVER; tries++)
{
    try 
    {
        admin = new Socket(host,port);
        os = admin.getOutputStream();
        is = new BufferedReader(new InputStreamReader(admin.getInputStream()));
        pw = new PrintWriter(new OutputStreamWriter(os));   

        AdminServerCommand.NODE_REGISTER.writeToPrintWriter(pw);
        pw.flush();

        sendPublicKey(os);

        String resultLine = null;
        resultLine = is.readLine();
        if(AdminServer.Feedback.KEY_REGISTERED.commandMatch(resultLine))
        {
            is.close();
            os.close();
            admin.close();
            return true;
        }
        is.close();
        os.close();
        admin.close();
        registerNodeRetrySleep(1000);
    }
    catch (Exception e) 
    {}
}
return false;

public void sendPublicKey(OutputStream out)
{
    try
    {
        ObjectOutputStream outO = new ObjectOutputStream(out);
        outO.writeObject(cyper.getPublicKey());
        outO.flush();
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }
}

public void writeToPrintWriter(PrintWriter os)
{
    if(os == null)
        throw new IllegalArgumentException("Can not write command to null stream.");
    os.println(comm);
    os.flush();
}

服务器使用

String com = "";
    try 
    {
        if(client.getInputStream().available() > 2)
        com = is.readLine();
    }
    catch (IOException e) 
    {
        errorResponse(Error.COMMAND_ERROR);
    }
    Key key = null;
    try
    {
        ObjectInputStream keyIn = new ObjectInputStream(client.getInputStream());
        key = (Key)keyIn.readObject();
    }
    catch(Exception b)
    {
        b.printStackTrace();
        errorResponse(Error.BAD_KEY);
        return;
    }

异常如下所示:

Nov 28, 2012 9:52:59 PM AdminServer.AdminServer run
INFO: Get a new request
java.io.StreamCorruptedException: invalid stream header: 73720014
    at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
    at java.io.ObjectInputStream.<init>(Unknown Source)
    at AdminServer.AdminServer.registerNewKeyEntry(AdminServer.java:115)
    at AdminServer.AdminServer.run(AdminServer.java:65)
    at java.lang.Thread.run(Unknown Source)
Nov 28, 2012 9:52:59 PM AdminServer.AdminServer errorResponse
WARNING: Error: Bad public key format. Use object stream with key object.

现在有没有人可以解决这个问题。类型 Key 是一个接口类型,它实现了自己的 Interface Serializable。所以序列化这个对象应该不是问题。我整个晚上都在处理这个问题。希望任何人都可以帮助我摆脱这个。

4

1 回答 1

1

您的问题中没有足够的代码来完全诊断 - 但这里有一些观察结果。

这段代码看起来很可疑:

if(client.getInputStream().available() > 2)
com = is.readLine();

大概您有一个is包装客户端输入流的缓冲阅读器。如果 if 语句不正确会发生什么 - 您跳过阅读该行?现在该行文本仍在管道中,并将传递给您的 keyIn.readObject 方法。这可能会导致损坏错误。

我建议只删除整if行。readLine() 无论如何都会阻塞,因此不需要检查。

另外,您是否绝对确定在AdminServerCommand.NODE_REGISTER.writeToPrintWriter(pw);换行后发送了一行完全没有字符的文本?

但是 - 我认为你在这里有一个更大的问题。这种在 Java 对象序列化和手动文本读取/写入之间来回切换的设计只是一场等待发生的灾难。如果要使用对象序列化,请独占使用它。您可以交替发送一个 String 对象,然后是一个 Key 对象,并且您的流不会因为您发送一个太多或一个两个几个换行符而损坏。

例如: ObjectOutputStream outO = new ObjectOutputStream(out);

    String command = "whatever";
    outO.writeObject(command);
    outO.writeObject(cyper.getPublicKey());
    outO.flush();

然后在服务器端,总是使用 readObject,知道第一个是命令,第二个是键。

于 2012-11-28T21:25:51.883 回答