繁体   English   中英

java nio socketChannel读取总是返回相同的数据

[英]java nio socketChannel read always return same data

在客户端,阅读代码:

byte[] bytes = new byte[50]; //TODO should reuse buffer, for test only
ByteBuffer dst = ByteBuffer.wrap(bytes);
int ret = 0;
int readBytes = 0;
boolean fail = false;
try {
    while ((ret = socketChannel.read(dst)) > 0) {
    readBytes += ret;
    System.out.println("read " + ret + " bytes from socket " + dst);
    if (!dst.hasRemaining()) {
        break;
    }
    }
    int pos = dst.position();
    byte[] data = new byte[pos];
    dst.flip();
    dst.get(data);
    System.out.println("read data: " + StringUtil.toHexString(data));
} catch (Exception e) {
    fail = true;
    handler.onException(e);
}

问题是socketChannel.read()总是返回正数,我检查了返回缓冲区,数据重复了N次,就像低级套接字缓冲区的位置不向前一样。 任何想法?

如果服务器仅返回48个字节,则您的代码必须在read()方法中被阻塞,试图获取第49个和第50个字节。 因此,要么您的“ 50”是错误的,要么您将不得不重组代码以读取和处理获得的内容,而不是先尝试填充缓冲区。 而且这可能不是您认为始终获得相同数据的代码。 如果您在下一次读取时重复使用相同的缓冲区,应该这样做,但是发布的代码却不执行,这样的解释将是在获取后无法压缩缓冲区。

1:这可能不是错误!

[假设缓冲区中有可读数据] ...

您可能希望流末尾为-1 ...请参阅http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/channels/SocketChannel.html#read%28java。 nio.ByteBuffer%29

如果您不断从read()调用中接收到正值,那么您将需要确定为什么要连续读取数据。

当然,这里的奥秘最终在于源数据(即从中读取数据的SocketChannel)。

2:您可能遇到的问题的说明

如果套接字通道来自有限的REAL文件,那么您的文件确实很大,并且最终,read()操作将返回0 ...最终...

另一方面,如果您的套接字通道正在侦听您期望是有限的数据源(例如,序列化的对象流),那么我将仔细检查该源-也许您的有限流只是在生成越来越多的数据...您正在正确地使用它。

3:最后一些建议

调试此类错误的一个技巧是将ByteBuffer输入读取方法中使用:关于java.nio的ByteBuffer的好处是,由于它们比旧的byte []编写器更面向对象,因此您可以-细粒度的操作调试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM