J'envoie une bufferedimage sur une prise et j'utilise l'exemple trouvé dans Ceci post:
expéditeur p> récepteur p> Ça fonctionne - si, et seulement si, et seulement si, et seulement si, et seulement si, Je ferme la sortie de l'expéditeur après cette ligne: p> InputStream in = clientSocket.getInputStream();
long startTime = System.currentTimeMillis();
byte[] b = new byte[30];
int len = in.read(b);
int filesize = Integer.parseInt(new String(b).substring(0, len));
if (filesize > 0)
{
byte[] imgBytes = readExactly(in, filesize);
FileOutputStream f = new FileOutputStream("C:\\Users\\Dan\\Desktop\\Pic\\1.jpg");
f.write(imgBytes);
f.close();
System.out.println("done");
3 Réponses :
Une option serait d'écrire l'image sur un puis sur l'extrémité de réception, vous pouvez lire La longueur, puis lisez que beaucoup d'octets dans une matrice d'octet, puis créez un Je ne suis pas entièrement surpris que cela ne fonctionne pas tant que la prise de sortie ne fonctionne pas normalement - après tout, un fichier contenant un fichier PNG valide et ensuite quelque chose d'autre em > N'est-ce pas un fichier PNG valide en soi, n'est-ce pas? Donc, le lecteur doit lire à la fin du flux avant de pouvoir terminer - et la "extrémité" d'un flux de réseau ne vient que lorsque la connexion est fermée. P> Edit: Voici une méthode pour lire les données nombre d'octets dans un nouveau réseau d'octets. Il est pratique d'avoir une méthode distincte "utilitaire". P> byteArrayOutPutStream code> afin que vous puissiez déterminer la longueur, puis écrivez en premier au flux de sortie en premier.
byteArrayInputStream code> pour envelopper la matrice et transmet que em> à
imageo.read () code >. p>
@David: C'est un code très convoluté - en particulier, vous ne devriez jamais attraper ArrayIndexoutofboundSException. Pourquoi n'utilisez-vous pas simplement out.write (imgbyte) code>? Et sur le côté de la réception, vous utilisez
client.getInputStream (). Lisez (tampon); code> qui est Ignorant complètement i> la valeur de retour de i> Lecture code> . Pas une bonne idée. Call
getinputtream () code> une fois i>, puis appelle
lire code> plusieurs fois, notant combien de données ont été lues sur chaque appel. Ne supposez pas que ce sera toujours la même que la taille de la réception.
Oui j'ai oublié de mentionner. Out.Write (imgbyte) oblige instantanément à la prise de courant et déconnecte le client. Je ne peux pas comprendre pourquoi cela se passe, mais je pensais qu'il doit y avoir une limite à la quantité de données que vous pouvez écrire à une fois, alors j'ai essayé de la scinder et de l'envoyer.
@David: Non, il devrait être absolument bien d'écrire des données sur une prise. Êtes-vous sûr que ce n'était pas le côté recevant i> qui a fermé la prise?
@David: Vous ignorez toujours la valeur de retour de entrée.Read () code>. Vous Ne devez pas I> faire ça. Vous devez faire boucle, entraînant de la quantité de données dont vous avez encore besoin de lire et de lire un morceau à la fois. Sur une connexion réseau, vous ne sera pas i> tout faire en une seule fois.
Cela a juste fait cette tentative modifiée 4. La réception ne donne aucune erreur. L'expéditeur, cependant, déconnecte simplement et dit "raccordement réinitialisé par pair" lorsque j'essaie d'écrire plus de 200 Ko à l'une à l'une d'abord sur le flux de sortie. Des idées?
@David: Eh bien, vous êtes maintenant écrasement i> les données à chaque fois - vous devez lire d'où vous êtes arrivé à i> dans le reste du tampon. Je suppose que vous avez réellement réussi à terminer la réception de toutes les données (par conséquent, vous fermez la prise), mais comme vous avez écrasé les données existantes sur chaque lecture, vous devez alors décoder l'image.
Et que suggérez-vous d'utiliser pour copier ce que j'avais eu du tampon dans Imgbyte? Système.arraycopy? Si c'est le cas, veuillez regarder la tentative n ° 3 et dites-moi pourquoi cela échoue.
@David: Vous pouvez lire directement dans imgbyte code>. Je vais ajouter un extrait de code rapide ... Notez que cela n'a rien à voir avec Image IMAGE.
Si vous êtes intéressé, jetez un coup d'œil à ce qui s'est passé. Si vous êtes fatigué de cela, je peux comprendre;)
@David: Oui, c'est exactement ce que je m'attendais - vous ne lisez jamais des données dans le début de la mémoire tampon. La plupart de votre fichier est donc vide. Avez-vous essayé l'extrait que j'ai fourni?
Cela utilise l'extrait que vous avez fourni. Remarquez l'octet de ligne [] imgbytes = readexactly (dans, platesize); Notez que je parle de tentative 5, recevez.
@David: J'ai maintenant remarqué comment vous écrivez la longueur dans le fichier. Ne fais pas ça! Vous lisez une quantité aléatoire de données jusqu'à 30 octets - rien ne garantit que ce que vous lisez sera une chaîne valide du tout. Ecrivez-le à l'aide de quelque chose comme dataOutputtream.writeint code> et lisez-le avec
DataGuTstream.readint code>. Vous devriez vérifier que vous transmettez correctement la taille la taille i> avant de partir ...
J'avais l'habitude d'avoir un système.Out.println (FileSize), mais je l'ai supprimé. C'était valable en premier lieu. (Bien que je suis d'accord c'est une mauvaise pratique). J'ai utilisé Evirsint maintenant et j'ai toujours exactement le même problème. Vous pouvez l'exécuter et voir si vous voulez.
@David: exactement i> le même problème? Les fichiers sont-ils de la même taille que l'autre maintenant? Est-ce qu'ils commencent i> avec les mêmes données? Je ne peux pas vraiment exécuter le code facilement sans dépenser de la quantité de temps à la fois définir tout le reste. Si vous pouviez modifier votre message sur juste i> une paire de clients / serveur courts mais complets à l'aide du dernier code, je verrai si je peux trouver le temps de diagnostiquer plus bien ce soir.
Pour les autres utilisateurs de Stackoverflow comme moi.
dans la réponse "Jon Skeet". Modifier la ligne de méthode suivante de la méthode ReadExacTly. P> pour obtenir les données d'image complètes. P> p>
public static void main(String[] args) { Socket socket = null; try { DataInputStream dis; socket = new Socket("192.168.1.48",8000); while (true) { dis = new DataInputStream(socket.getInputStream()); int len = dis.readInt(); byte[] buffer = new byte[len]; dis.readFully(buffer, 0, len); BufferedImage im = ImageIO.read(new ByteArrayInputStream(buffer)); jlb.setIcon(new ImageIcon(im)); jfr.add(jlb); jfr.pack(); jfr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jfr.setVisible(true); System.gc(); } } catch (Exception e) { e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } In 192.168.1.48:8000 machine python server running and i got stream in java code