我遇到了一个我发现并希望在我的应用中实现的java.nio非阻塞服务器的问题:
所以这就是发生的事情: 每隔一段时间,它就有效。它可以连接到服务器,进行小握手并准备好来回传递消息。但通常情况下,它甚至没有得到连接的信息。以下是握手的工作原理:
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
加密提及使用jasypt。
每次尝试时,这都适用于Android 2.2,2.3和Mac OS X(Java 1.6)。它在每个服务器生命周期(启动,运行,死亡)期间在高于3.0的Android版本上运行一次。我知道Android的网络方式发生了重大变化,但我所知道的唯一一个就是你不能在主线程上做网络(这不是,这是一个从服务中产生的线程。)我是与tcpdump
确认服务器实际上正在发送连接的消息。
任何帮助都会很棒,只是在Android 3 +中才会出现故障。
提前感谢您的帮助。
编辑:我没有说明握手失败的位置。客户端收到密码后失败。通过调试,我知道客户端也在获取连接消息,因为它不是读取缓冲区上的唯一内容:
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)...]
0,16
和0,32
是消息长度(分别为16和32)。这是在TwoByteMessageLength.java中定义的。
此外,它可能不是加密失败,因为这会引发一个很大的“EncryptionOperationNotPossibleException
例外。”
答案 0 :(得分:0)
好吧,问题就是这样:
在手机正在播放的阵列中,两个消息都立即进入(看看问题,看看我的意思)。它只读取所有内容(由于InputStream.read()
返回整个缓冲区的长度)但接受其中一些(由于长度标题)。在读取开头的16字节消息并将其从缓冲区中清除后,它再次读取其空间中的零。
解决方案?使服务器在密码共享和连接的消息之间屏住呼吸。事实证明这是一个“好”的问题 - 我的手机太快了。这就是为什么它在带有旧软件的模拟器中工作的原因。 (另外我有一个闪电般快速的Nexus 4,因此可能有所贡献。)