2013-07-01 2 views
0

Je vais avoir un problème avec un serveur java.nio non bloquant que j'ai trouvé et que vous souhaitez mettre en œuvre dans mon application:Problème avec java.nio dans Android 3+

https://code.google.com/p/java-toys/source/browse/#svn%2Ftrunk%2FExample_NIO_Server%2Fsrc%2Fcom%2Fcordinc%2Futil%2Fnetwork

Alors, voici ce qui est passe: De temps en temps, ça marche. Il peut se connecter au serveur, faire sa petite poignée de main et être prêt pour les messages d'avant en arrière. Mais le plus souvent, il n'obtient même pas le message connecté. Voici comment fonctionne la prise de contact:

Server sends cipher for encryption 
Server sends "connected" to test connection and encryption 
Client sends username 
Server sends acknowledgment 
Client sends password 
Server sends acknowledgement 
Server sends login success if that's the case 
Client sends acknowledgment of login 
Server asks for uuid 
Client provides uuid 
Server says it's ready 
Client says it's ready 
The handshake is complete and message transfer can begin 

Les mentions de chiffrement utilisent jasypt.

Et cela fonctionne sur Android 2.2, 2.3 et Mac OS X (Java 1.6) chaque fois que je l'essaie. Il fonctionne une fois au cours de chaque cycle de vie du serveur (démarrer, exécuter, mourir) sur les versions d'Android supérieures à 3.0. Je sais qu'il y a eu des changements significatifs dans la manière dont Android fonctionne en réseau, mais le seul que je connaisse est que vous ne pouvez pas faire de réseau sur le thread principal (ce qui n'est pas le cas, c'est un thread généré par un service). confirmé avec tcpdump que le serveur envoie réellement un message connecté.

Toute aide serait géniale, c'est bizarre qu'elle se casse seulement dans Android 3+.

Nous vous remercions de votre aide à l'avance.

Modifier: Je n'ai pas précisé où l'établissement de liaison échoue. Il échoue après que le client a reçu le chiffrement. Via le débogage, je sais que le client obtient également le message connecté car ce n'est pas la seule chose sur la mémoire tampon de lecture:

Cipher: 
[0, 16, 102, 69, 106, 80, 101, 56, 77, 72, 118, 117, 77, 75, 85, 100, 57, 78, 
Connected: 
0, 32, 53, 106, 43, 69, 104, 122, 87, 100, 109, 67, 85, 90, 121, 65, 83, 57, 98, 65, 78,  73, 103, 103, 66, 55, 103, 54, 55, 106, 54, 108, 54, 53, ...(Rest of buffer is zeros)...] 

Le 0,16 et 0,32 sont les longueurs de message (16 et 32 ​​respectivement). Cela est défini dans TwoByteMessageLength.java.

En outre, ce n'est probablement pas le chiffrement qui échoue car cela provoquerait une grosse erreur EncryptionOperationNotPossibleException.

+1

Et si des exceptions se produisaient sur le côté client Android, y a-t-il une place dans la poignée de main décrite comme une erreur? un wakelock Android pendant vos opérations? –

+0

Il n'y a aucune exception levée par le côté Android. Je n'ai pas de verrou de réveil, et j'ai édité la question à propos de l'échec de la poignée de main parce que je pensais que cela pourrait le clarifier. –

+0

Y at-il une bonne raison pour laquelle vous n'utilisez pas SSL pour cela? – EJP

Répondre

0

Bon, alors voici était le problème:

Dans le tableau le téléphone recevait, les deux messages arrivaient à la fois (regarder question pour voir ce que je veux dire). Il ne lisait que tout (en raison de InputStream.read() retournant la longueur de la mémoire tampon entière) mais en acceptant une partie (en raison de l'en-tête de longueur). Après avoir lu le message de 16 octets au début et l'avoir effacé du tampon, il a de nouveau lu les zéros dans son espace.

La solution? Faites respirer le serveur entre le partage de chiffrement et le message connecté. Il s'est avéré que c'était un "bon" problème - mon téléphone est trop rapide. C'est pourquoi cela a fonctionné dans un émulateur avec un vieux logiciel. (De plus, j'ai un Nexus 4 rapide comme l'éclair, donc cela peut avoir contribué.)