2012-11-28 107 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

重新設計後感謝,看起來相當不錯。 –