Вопрос

I'm having an issue with a java.nio non-blocking server that I found and want to implement in my app:

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

So here's what's happening: Every-so-often, it works. It can connect to the server, do it's little handshake and be ready for messages back and forth. But more often than not, it doesn't even get the connected message. Here's how the handshake works:

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

The encryption mentions is using jasypt.

And this works on Android 2.2, 2.3, and Mac OS X (Java 1.6) every time I try it. It works once during each server life cycle (start, run, die) on versions of Android higher than 3.0. I know there were significant changes to how Android does network, but the only one I know is that you can't do network on the main thread (which this isn't, this is a thread spawned from a service.) I've confirmed with tcpdump that the server is actually sending a connected message.

Any help would be great, it's weird that it breaks only in Android 3+.

Thank you for any help in advance.

Edit: I didn't make clear where the handshake fails. It fails after the client receives the cipher. Via debugging, I know that the client is also getting the connected message because it's not the only thing on the read buffer:

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)...]

The 0,16 and 0,32 are the message lengths (16 and 32, respectively). That is defined in TwoByteMessageLength.java.

Furthermore, it's probably not the encryption failing because that would throw a big ol' EncryptionOperationNotPossibleException exception.

Это было полезно?

Решение

Alright, so here was the problem:

In the array the phone was getting, both messages were coming in at once (look at question to see what I mean). It was only reading all of it (due to InputStream.read() returning the length of the entire buffer) but accepting some of it (due to the length header). After it read the 16 byte message at the beginning and cleared it from the buffer, it read the zeros in it's space again.

The Solution? Make the server take a breath between the cipher share and the connected message. It turns out it was a "good" problem - my phone is too fast. That's why it worked in an emulator with old software. (Plus I have a lightning fast Nexus 4, so that may have contributed.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top