繁体   English   中英

为什么输入流以块的形式读取数据?

[英]Why does input stream read data in chunks?

我试图使用以下代码从网络套接字读取一些数据 -

Socket s = new Socket(address, 502);
response = new byte[1024];
InputStream is = s.getInputStream();
int count = is.read(response, 0, 100);

数据量不大。 它总共是16个字节。 但是read()语句不能一次读取所有数据。 它只能将8个字节的数据读入我的缓冲区。

我必须多次调用read()才能读取数据 -

Socket s = new Socket(address, 502);
response = new byte[1024];
InputStream is = s.getInputStream();
int count = is.read(response, 0, 100);
count += is.read(response, count, 100-count);

为什么会这样? 为什么read()不能一次读取整个流?

请注意,数据不会逐渐到达。 如果我在通过调用Thread.sleep(2000)读取数据之前等待2秒,则行为保持不变。

为什么read()不能一次读取整个流?

因为没有指定这样做。 见Javadoc。 它会阻塞,直到至少有一个字节可用,然后返回介于1和所提供长度(包括1和1)之间的某个数字。

这反过来是因为数据不一定一次到达。 您无法控制TCP如何发送和接收数据。 您有义务将其视为字节流。

我知道它会阻止数据到达。 “这反过来是因为数据不一定一次到位。” 为什么不是我的问题。

数据不一定全部到达,因为网络通常将其分解为数据包。 IP是分组交换协议。

TCP是否传输8字节的块?

可能,但可能不是。 数据包大小取决于数据遍历的网络/网络,但典型的Internet数据包大小约为1500字节。

如果您一次获得8个字节,则您的数据要么通过具有异常小的数据包大小的网络,要么(更有可能)发送方一次发送8个字节的数据。 第二种解释或多或少与你的其他评论所说的一致。

既然我明确指定了100,那么一个比缓冲区中的数据大得多的数字不应该尝试读取直到至少100个字节?

好吧不。 它没有指定以这种方式工作,并且它不起作用。 您需要根据规范说明编写代码。


这可能与设备被“轮询”的方式有关。 但是,如果不查看设备的规格(甚至不知道它究竟是什么),这只是猜测。

也许数据逐渐到来不是因为你的阅读而是因为发件人。

发送方应该使用BufferedOutputStream (在中间)在发送之前制作大块(并且仅在需要时使用flush)。

暂无
暂无

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

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