2012-11-28 2 views
0

J'essaie d'envoyer un objet clé publique de type clé à mon serveur. Mais je ne l'ai pas fait courir. Le prototocl regarde les éléments suivants:Utilisez ObjectStreams sur Sockets pour transférer l'objet clé Java

[Commande] \ n [sérialisé objet clé]

Le client utilise ce code:

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(); 
} 

Le serveur utilise

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; 
    } 

Les regards d'exception ce qui suit:

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. 

Est-ce que quelqu'un maintenant comment je peux résoudre ce problème. Le type Key est un type d'interface qui implémente lui-même l'interface Serializable. Cela ne devrait donc pas poser de problème pour sérialiser cet objet. Je passe toute la soirée avec ce problème. J'espère que tout le monde peut m'aider à m'en débarrasser.

+0

Quel type de clé publique vous essayez de transférer? RSA? Btw assurez-vous de les transférer sur une connexion sécurisée - sinon ces clés ne doivent pas être approuvées. –

+0

Désolé, c'est la clé publique RSA. La chaîne sera enregistrée pour la transmission. –

+0

Une raison pour laquelle vous n'utilisez pas SSL? Ou envoyer un certificat au lieu de simplement sa clé publique? – EJP

Répondre

1

Il n'y a pas assez de code dans votre question pour diagnostiquer complètement - mais voici quelques observations.

Ce code semble suspect:

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

On peut supposer que vous avez un lecteur tampon is enveloppant le flux d'entrée du client. Que se passe-t-il si l'instruction if n'est pas vraie - vous passez la ligne? Maintenant, cette ligne de texte est toujours dans le pipeline et passera à votre méthode keyIn.readObject. Cela pourrait provoquer l'erreur de corruption.

Je recommande simplement de supprimer toute la ligne if. readLine() bloque de toute façon, donc la vérification n'est pas nécessaire.

Également, êtes-vous absolument sûr que AdminServerCommand.NODE_REGISTER.writeToPrintWriter(pw); envoie exactement une ligne de texte avec absolument aucun caractère après le saut de ligne?

Cependant - je pense que vous avez un plus gros problème ici. Cette conception dans laquelle vous alternez entre la sérialisation d'objets Java et la lecture/écriture manuelle de texte est juste une catastrophe qui attend de se produire. Si vous souhaitez utiliser la sérialisation d'objets, utilisez-la exclusivement. Vous pouvez alterner l'envoi d'un objet String, puis d'un objet Key et votre flux ne sera pas corrompu car vous avez envoyé un trop ou un deux peu de sauts de ligne. Par exemple: ObjectOutputStream outO = new ObjectOutputStream (out);

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

Puis sur le côté serveur, utilisez toujours readObject, sachant que la première sera une commande, la seconde sera une clé.

+0

Les bons points vont essayer ceci et vous parler de mes résultats. –

+0

Merci après la refonte, il semble assez bon. –