2010-06-23 6 views
1

J'essaie d'écrire des données dans un socket de données brutes (environ 22 Mo). Le scénario est tel: -Difficulté à utiliser les sockets Flash/Adobe Air 2.0

  1. Ouvrir fichier local
  2. Lire un morceau d'octets.
  3. Ecrivez-le sur le socket
  4. Répétez 2 & 3 jusqu'à la fin du fichier.

Maintenant le problème est que mon code (ci-dessous) ne transfère pas le fichier complet. Il transfère peut-être 3 sur les 22 Mo avec mon fichier de test. La trace est cependant complète et montre des données complètes en cours de transmission. Je soupçonne que peut-être il commence à écrire le morceau suivant avant de finir le courant (bien que je ne sois pas sûr).

while(fs.bytesAvailable > 0){ 
    var readAmount = (fs.bytesAvailable < socketBufferSize) ? fs.bytesAvailable : socketBufferSize; 
    seq++; 
    air.trace(">"+seq+" WritePacket "+readAmount+" "+fs.position+" "+fs.bytesAvailable); 
    fs.readBytes(bytes, 0, readAmount); 
    air.trace(bytes.length); 
    socket2.writeBytes(bytes, 0, bytes.length); 
    socket2.flush(); 
} 
fs.close(); 
socket2.close(); 

Ci-dessus est le code que je suis censé utiliser. Je voudrais savoir si je fais quelque chose de bien ou de mal.

L'insertion d'un délai forcé entre les itérations d'écriture garantit que le fichier est transféré complètement indiqué dans l'extrait ci-dessous. Cependant, ce n'est pas une solution acceptable. Je voudrais savoir s'il y a un événement auquel je devrais être abonné ou si quelque chose doit être fait différemment. Le serveur à l'autre extrémité est le serveur FTP FileZilla.

var sendData = function(){ 
    if(fs.bytesAvailable > 0){ 
    var readAmount = (fs.bytesAvailable < socketBufferSize) ? fs.bytesAvailable : socketBufferSize; 
    seq++; 
    air.trace(">"+seq+" WritePacket "+readAmount+" "+fs.position+" "+fs.bytesAvailable); 
    fs.readBytes(bytes, 0, readAmount); 
    air.trace(bytes.length); 
    socket2.writeBytes(bytes, 0, bytes.length); 
    socket2.flush(); 
    } 
    else{ 
     air.trace("Closing Connection"); 
     fs.close(); 
     socket2.close(); 
    } 
} 
var interval = setInterval(sendData, 100); 

Merci

+0

Apparemment, le problème réside dans le fait que la fonction de fermeture de socket est brutale. Il ferme prématurément le canal avant qu'il ait une chance de transférer toutes les données. Si je supprime le socket.close() et attendez qu'il expire il fonctionne correctement. Y a-t-il une manière correcte recommandée pour faire ceci? –

+0

Oh et si ce problème vous afflige, alors s'il vous plaît voter pour ce numéro: http://bugs.adobe.com/jira/browse/FP-6 –

+0

Ce problème a été confirmé par l'équipe de l'air sur le groupe google étanche à l'air . Heres le message transféré: - Le problème que vous rencontrez ici est que si vous appelez close() trop tôt, les données qui n'ont pas encore été transmises sont rejetées et le socket est immédiatement fermé. C'est pourquoi l'insertion d'un retard fonctionne: il donne le temps pour les données à transmettre avant d'appeler close(). Nous (l'équipe AIR) sommes conscients qu'il s'agit d'un problème d'utilisabilité plutôt important dans cette API, et nous travaillons à y remédier. En attendant, je crois qu'un délai est votre meilleure option. Cordialement, Oliver –

Répondre

0

Depuis AIR a une prise brutale étroite, le serveur doit être modifié pour laisser le client savoir quand il a reçu toutes les données envoyées (via un autre contrôle TCP Socket). Bien sûr, le client doit transmettre le nombre de données qu'il envoie au départ.

0

Il a été un moment que je suis en attente d'un événement de prise déclenché lorsque les données sont entièrement écrit ... :(

La première idée est de mettre un retard après chaque écriture(). Toutefois, en cas de très bonne connexion, le transfert est plus long à cause du retard et en cas de connexion lente, le délai n'est pas toujours suffisant et donc certaines données peuvent encore être perdues :(

La seule solution que j'ai trouvée n'est pas vraiment correct, mais fonctionne.J'utilise proftpd comme serveur FTP avec un MOD que j'ai écrit qui permet une nouvelle commande FTP: FILESIZE Cette commande donne la taille d'un chemin de fichier en octets

Puis, en flex, j'ai 2 sockets ouvertes: une pour transmettre les données, une pour récupérer la taille du fichier. Après chaque appel de write() sur le premier socket, j'obtiens la taille du fichier en utilisant FILESIZE sur le second socket.

L'autre côté de la pièce est que le transfert prend beaucoup de temps à cause des appels FTP de FILESIZE (: /) mais le transfert est plus fiable.

C'est le genre de problème qui passera probablement de Flex à Java. Alomost deux ans ce problème est publié sur les pages de bogues Adobe, et ... rien ... Y at-il un moyen d'ajouter cette fonctionnalité dans le noyau de flex? Je ne pense pas, flash n'est pas open source ...

+0

Vince. Je serais vraiment génial si vous pouviez partager le code de la commande FILESIZE proftpd MOD. –

Questions connexes