【问题标题】:Data loss during high speed transfer over SocketChannel通过 SocketChannel 进行高速传输期间的数据丢失
【发布时间】:2014-11-06 21:29:44
【问题描述】:

我正在开发 Android 应用程序,手机在哪里通过 Wifi-Direct 执行一些计算。 就我而言,效率至关重要。我的协议的瓶颈是网络。我使用SocketChannel 接收/传输数据。 这是我的伪代码:

byte[] array = new byte[]{20,20,20,20,20,20,20,20,20,20};
        for (int i=0; i<10; i++)
        {
            ByteBuffer sendBB = ByteBuffer.allocate(buffSize);
            sendBB.put(array, 0, array.length);
            sendBB.rewind();
            ByteBuffer receiveBB = ByteBuffer.allocate(buffSize);

            try {

                socketChannel.read(receiveBB);
                socketChannel.write(sendBB);

                byte[] received = new byte[10];
                receiveBB.rewind();
                receiveBB.get(received, 0, 10);
                Log.i("Received", Arrays.toString(received));           


            } catch (IOException e) {
                e.printStackTrace();
            }
        }

类似的代码是给对方的。 连接是这样创建的:

serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(socketAddress);           
socketChannel = serverSocketChannel.accept();

事实证明,当buffSize 很小时,一切都传输良好:100、200。 当它是 500 或更高时,我会丢失数据。我收到类似的东西:

[20,20,20,20,20,20,20,20,20,20]
[0,0,0,0,0,0,0,0,0,0]
[20,20,20,20,20,20,20,20,20,20]
[20,20,20,20,20,20,20,20,20,20]
[0,0,0,0,0,0,0,0,0,0]
[0,0,0,0,0,0,0,0,0,0]
[20,20,20,20,20,20,20,20,20,20]
[20,20,20,20,20,20,20,20,20,20]
[20,20,20,20,20,20,20,20,20,20]
[20,20,20,20,20,20,20,20,20,20]

更高的缓冲区让位于更高的速度。有没有办法,如何保持速度并防止数据丢失? 谢谢

【问题讨论】:

    标签: java android networking nio socketchannel


    【解决方案1】:

    常见问题。

    socketChannel.read(receiveBB);
    socketChannel.write(sendBB);
    

    您忽略了read()write() 返回的长度。

    byte[] received = new byte[10];
    receiveBB.rewind();
    receiveBB.get(received, 0, 10);
    

    这都是错误的。应该是:

    int count = socketChannel.read(receiveBB);
    byte[] received = new byte[count];
    receiveBB.flip();
    receiveBB.get(received);
    receiveBB.compact();
    

    如果您希望收到固定长度的消息,则必须循环播放,直到获得所有消息。 read() 没有义务填充缓冲区。

    【讨论】:

    • 就我而言,我想传输小消息,例如 10 个字节。我将它们放入大 ByteBuffer 以加快传输速度。
    • @Sparrow_ua 无论您的缓冲区大小如何,仍然无法保证 read() 会在第一次调用时将其填满,也无法保证 write() 会在一次调用中有效地将其全部写入。阅读read()write()的javadoc,可以看到读取或写入的字节数可以从0到缓冲区的remaining()size
    • 我循环了读和写方法(以确保所有内容都是读/写的),但它严重减慢了传输速度。有没有其他快速传输的方法?
    【解决方案2】:

    通过循环读写解决问题:

    int countWritten=0;
    while (countWritten < buffSize)
    {
        countWritten+=socketChannel.write(sendBB);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      • 1970-01-01
      • 2021-10-29
      相关资源
      最近更新 更多