2016-04-18 1 views
0

je travaille sur un projet client/serveur en Java où, à tout moment au cours de l'exécution du programme, le client peut demander un ensemble de détails associé à un ID unique et le serveur renvoie l'ensemble de détails pertinent. Ceci est fait à travers PrintWriter objets accédant au socket.getOutputStream, et fonctionne très bien.Java - Envoi de ImageIcon par ObjectOutputStream fonctionne première fois, mais pas après

Je suis en train d'inclure aussi l'envoi/réception d'une image du serveur vers le client, et ont rencontré un comportement très étrange du programme.

Les méthodes qui envoient et reçoivent les images sont présentées ci-dessous:

côté serveur:

//send image associated with item 
//through ObjectOutputStream to client 
private void sendItemImage(BidItem item) 
{ 
    try 
    { 
     //wrap object output stream around 
     //output stream to client at this socket 
     ObjectOutputStream imageOutput = 
       new ObjectOutputStream(client.getOutputStream()); 
     //send image object to client 
     imageOutput.writeObject(item.getItemImage()); 
    } 
    catch (IOException ioEx) 
    { 
     //alert server console 
     System.out.println("\nUnable to send image for item " 
         + item.getItemCode() + " to " 
         + bidderName + "!"); 
     //no exit from system 
     //bidding can still continue 
    } 
} 

côté client:

//to be displayed on GUI 
private static void receiveItemImage() 
{ 
    try 
    { 
     //wrap ObjectInputStream around socket 
     //to receive objects sent from server 
     ObjectInputStream imageInput = 
       new ObjectInputStream(socket.getInputStream()); 
     //read in image and store in ImageIcon instance 
     image = (ImageIcon) imageInput.readObject(); 

     //re-create label object to be blank 
     imageLabel = new JLabel(); 
     //remove label containing last image 
     imagePanel.remove(imageLabel); 
     //just ignores command if it does not already contain image 

     //apply image to label 
     imageLabel.setIcon(image); 
     //apply image to CENTER of panel 
     imagePanel.add(imageLabel, BorderLayout.CENTER); 
    } 
    //problem in input stream 
    catch (IOException ioEx) 
    { 
     //alert user 
     JOptionPane.showMessageDialog(
       null, "Error receiving image!"); 
     //allow system to continue 
     //no exit 
    } 
    //problem casting to ImageIcon type 
    catch (ClassNotFoundException cnfEx) 
    { 
     //alert user 
     JOptionPane.showMessageDialog(
       null, "Error converting Object to ImageIcon!"); 
     //allow system to continue 
     //no exit 
    } 
} 

Donc, chaque fois qu'il ya une demande , un ObjectOutpuStream et ObjectInputStream sont créés pour gérer le passage de l'image, en utilisant le socket.getOutputStream/socket.getInputStream.

Ces méthodes sont d'abord appelés lorsqu'un client se connecte au serveur, et la première image et un ensemble de détails sont envoyés automatiquement. Cela fonctionne correctement, mais toutes les tentatives ultérieures de demande de l'image dans le programme aboutissent à la clause catch (IOException) et les messages d'erreur ci-dessus sont affichés.

Je ne peux pas pour la vie de me comprendre pourquoi cela fonctionnerait la première fois mais pas encore après cela. Si quelqu'un pouvait me diriger dans la bonne direction, ce serait génial!

Merci, Mark

+0

Juste avant chaque 'JOptionPane.showMessageDialog()', pouvez-vous ajouter une trace de pile: 'ioEx.printStackTrace(); – Saheed

Répondre

1

Vous ne devez envelopper un flux une fois. Dans ce cas, vous ne pouvez pas l'envelopper à nouveau car cela ne fonctionnera pas pour un flux d'objets.

Une fois que vous envelopper le flux qu'une seule fois, appelez ObjectOutputStream.reset() après l'envoi d'une image. Si vous ne le faites pas, il suffit de repasser la référence à l'objet (et d'utiliser beaucoup de mémoire)

+0

Est-ce toujours le cas même si l'instance 'ObjectOutputStream' est créée et détruite avec chaque appel de fonction? Et si je n'ai besoin de l'assigner qu'une seule fois, cela aurait-il un sens de le faire déclarer globalement? – marcuthh

+0

Où que vous stockez le Socket je voudrais également stocker les ObjectInputStream et ObjectOutptuStream. Vous devriez toujours envelopper le flux une seule fois, peu importe comment vous le faites. –

+0

Ok, merci beaucoup de l'avoir signalé! – marcuthh