Android *** 服务 Bytebuffer 无法写入

Posted

技术标签:

【中文标题】Android *** 服务 Bytebuffer 无法写入【英文标题】:Android *** service Bytebuffer can't be written 【发布时间】:2018-06-11 01:00:02 【问题描述】:

我正在开发一个带有 *** 服务的数据包嗅探器 android 应用程序,但我在将数据包从 Fileinputstream 读取到 bytebuffer 时遇到了麻烦。问题是每次我将数据包写入字节缓冲区时,字节缓冲区内都没有任何数据。请帮帮我。谢谢

 FileInputStream in = new FileInputStream(traffic_interface.getFileDescriptor());

                FileOutputStream out = new FileOutputStream(traffic_interface.getFileDescriptor());
                DatagramChannel tunnel = DatagramChannel.open();
                if (!protect(tunnel.socket())) throw new IllegalStateException("Cannot protect the tunnel");

                tunnel.connect((new InetSocketAddress("127.0.0.1",0)));
                tunnel.configureBlocking(false);
                int n = 0;

                while (!Thread.interrupted())
                    packet = ByteBuffer.allocate(65535);

                    int packet_length = in.read(packet.array());
                    Log.d("UDPinStream","UDP:" +packet_length);

                    if(packet_length != -1 && packet_length > 0)
                        Log.d("UDPinStream","UDP:" + packet_length);
                        Log.d("UDPinStream","packet:" + packet);

                        packet.clear();
                    

问题出现在以下代码中

                int packet_length = in.read(packet.array());

                if(packet_length != -1 && packet_length > 0)
                    Log.d("UDPinStream","UDP:" + packet_length);
                    Log.d("UDPinStream","packet:" + packet);

                    packet.clear();
                

虽然它成功地从隧道中读取了数据包(packet_length >0),但Bytebuffer中也没有数据packet bytebuffer的位置没有改变。 java.nio.HeapByteBuffer[pos=0 lim=65535 cap=65535]

【问题讨论】:

【参考方案1】:

ByteBuffers 旨在与通道一起使用。您应该使用通道的任何读/写(ByteBuffer buf)接口来正确使用 ByteBuffer。

无论如何,在您的 sn-p 中,read() 获取 byte[],写入其中,但 ByteBuffer 不知道其支持的数组已填充。所以,你可以这样做,

if (packet_length != -1 && packet_length > 0) 
    packet.position(packet_length);  // filled till that pos
    packet.flip();                   // No more writes, make it ready for reading

   // Do read from packet buffer
   // then, packet.clear() or packet.compact() to read again.

在继续之前,请查看 NIO / ByteBuffer 示例。

【讨论】:

我明白了,写入ByteBuffer时ByteBuffer的pos是否不会改变?当我通过调用 write(packet) 方法写入 DatagramChannel 时遇到了另一个麻烦。我得到 java.io.IOException: Invalid argument error 如果调用channels的write/read方法,方法返回时bytebuffer的位置会改变。我不确定你是如何得到这个异常的,但是 udp 要求写缓冲区不大于操作系统缓冲区大小和最大数据报大小,读缓冲区至少与接收到的数据报包一样大。因此,如果您的操作系统的发送缓冲区大小为 4096,并且您正在传递大小为 64k 的字节缓冲区,这应该会引发异常。 在你的例子中,非阻塞并不意味着什么,所以首先开始使用阻塞。设置接收缓冲区和发送缓冲区大小,然后重试。 tunnel.setOption(StandardSocketOptions.SO_RCVBUF, 60000); tunnel.setOption(StandardSocketOptions.SO_SNDBUF, 60000); 写的问题我终于解决了。好像我忘记添加数据报套接字来监听相关端口,当我更改为阻塞模式时,通道不再工作,我认为它应该使用通道的发送/接收方法而不是阻塞模式下的读/写正确的?现在我无法从隧道中读取数据包数据。每次调用 int k = tunnel.read(packet_received); 时我都得到 k=0; 如果你打算使用非阻塞,你需要选择器告诉你频道已经准备好被读取。如果您使用阻塞,您的线程会等待读取调用,直到收到消息。无论哪种方式,您都必须使用通道的读/写 (Bytebuffer b) 调用。对通道读取的阻塞调用不会返回“0”,所以我猜它仍然处于非阻塞模式。

以上是关于Android *** 服务 Bytebuffer 无法写入的主要内容,如果未能解决你的问题,请参考以下文章

Android ByteBuffer.asXxxBuffer 忽略位置?

Android jni 数据类型丢失精度(ByteBuffer,int)

ByteBuffer 在特定版本的 Android 上抛出 UnsupportedOperationException

Honeycomb 下的 Android 不支持 Bytebuffer array() 方法

如何在android的MediaCodec上下文中使用ByteBuffer

来自 NIO Direct ByteBuffer 的 Android RenderScript 分配副本