2012-11-28 108 views
0

我正在尝试向我的服务器发送一个Key类型的公共对象。但我没有得到这个运行。该prototocl看起来如下:通过套接字使用ObjectStreams来传输Java密钥对象

[命令] \ 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接口。因此,序列化这个对象应该不成问题。我整个晚上都在解决这个问题。希望有人能帮助我摆脱这一点。

+0

你正尝试传输什么类型的公钥? RSA?顺便说一句,确保你通过安全连接传输它们 - 否则这些密钥不应该被信任。 –

+0

对不起,这是公共RSA密钥。该频道将被保存用于传输。 –

+0

您没有使用SSL的某些原因?或者发送证书而不是公钥? – EJP

回答

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,知道第一个将是一个命令,第二个将是一个键。

+0

好点将尝试这个并告诉你我的结果。 –

+0

重新设计后感谢,看起来相当不错。 –