使用套接字上的ObjectStreams传输Java密钥对象



我正在尝试将key类型的公钥对象发送到我的服务器。但我没有跑完。prototocl看起来如下:

[Command]\n[serialized Key object]

客户端使用以下代码:

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。所以序列化这个对象应该不会有问题。我整个晚上都在处理这个问题。希望有人能帮我摆脱这一切。

您的问题中没有足够的代码来完全诊断,但以下是一些观察结果。

此代码看起来可疑:

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

假设您有一个缓冲读取器is来包装客户端输入流。如果if语句不是真的——你跳过了读这一行,会发生什么?现在,这行文本仍在管道中,并将传递给keyIn.readObject方法。这可能会导致损坏错误。

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

此外,你绝对确定AdminServerCommand.NODE_REGISTER.writeToPrintWriter(pw);在换行后只发送一行完全没有字符的文本吗?

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

例如:ObjectOutputStream outO=新的ObjectOutputStream(out);

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

然后在服务器端,始终使用readObject,知道第一个将是命令,第二个将是密钥。

最新更新