关于InputStream.read()方法的阻塞原理的测试
最近在一家公司做java实习,写了个网络字节采集器。写了个单例TCPServer来采集数据,其中用到了InputStream.read()来读取数据。产生了一系列问题,下面做下总结:
关于while((length = is.read(data)) != -1)问题。
在写此方法时,产生了一些疑惑,read何时阻塞?何时返回值-1?
首先做个假设:
1、读不满data的length就一直阻塞。为此,做了以下实验:
Server端:
byte[] data = new byte[8];
while((length = is.read(data)) != -1){
String result = new String(data);
System.out.println(result);
System.out.println("length:" + length);
}
客户端:
String msg = "ab";
byte[] byteMsg = msg.getBytes();
Socket socket = new Socket("127.0.0.1", 9999);
OutputStream out = socket.getOutputStream();
BufferedOutputStream bw = new BufferedOutputStream(out);
for (int i = 0;i<10;i++) {
bw.write(byteMsg);
bw.flush();
}
发现服务端在length=2时,就输出了,结果为ab。说明并不是在data读不满时就一直阻塞。
2、那么是不是跟flush()有关呢?
下面将bw.flush()注视,发现,并追加代码Thread.sleep(5*1000),让它每次输出2个字节后暂停5秒,以达到网络很差的目的。发现服务端每次输出abababab 8个长度的字节。则可以判定跟flush有关。
3、那什么时候缓冲区的数据会flush呢?
和另一网络组的程序对接读数据,他每次都发送148个字节长度的数据,并循环一直发,而我这边依次解析148长度的数据。但发现时间久了数据就会对不拢。分析错误数据发现是没有读完148,而下次再读时将剩余没读完的部分加在了本次的头部,固然出错。于是有个疑问:我这边每次都是读148个字节,然后处理,为什么会有读不满148的情况?根据前两个的测试,初步判断跟flush有关。可能是网络层数据缓冲区在数据量超过一定范围时自动flush了。测试如下:
客户端:
String msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] byteMsg = msg.getBytes();
try {
Socket socket = new Socket("127.0.0.1", 9999);
OutputStream out = socket.getOutputStream();
BufferedOutputStream bw = new BufferedOutputStream(out);
for (;;) {
bw.write(byteMsg);
//这里不进行程序flush,一直发。
}
服务端:
int count = 1000000;
is = socket.getInputStream();
byte[] data = new byte[count];
int length = 0;
while((length = is.read(data)) != -1){
String result = new String(data);
System.out.println(result);
System.out.println("length:" + length);
}
发现输出如下:
aaaaaaa..............行太长
length:39960
aaaaaaa..............行太长
length:23976
aaaaaaa..............行太长
length:23976
aaaaaaa..............行太长
length:24745
aaaaaaa..............行太长
length:25435
aaaaaaa..............行太长
length:21748
说明网络层缓冲区在长度一定时,就自动flush,但是这个长度好像不是很固定。长度取决于什么现在还不清楚。
关于InputStream.read()方法的阻塞原理的测试的更多相关文章
- [Android Pro] 关于inputStream.available()方法获取文件的总大小
reference to :http://hold-on.iteye.com/blog/1017449 如果用inputStream对象的available()方法获取流中可读取的数据大小,通常我们调 ...
- (判断url文件大小)关于inputStream.available()方法获取下载文件的总大小
转自:http://hold-on.iteye.com/blog/1017449 如果用inputStream对象的available()方法获取流中可读取的数据大小,通常我们调用这个函数是在下载文件 ...
- Sleeping会话导致阻塞原理(下)
背景 最近给客户做优化时,有几个客户都存在.SLEEPING 会话中开启了事务,导致的大量阻塞,从而产生严重的性能问题.虽然在之前的文章我分享了Sleeping会话导致阻塞原理(上) .说明了什么是S ...
- 机器学习中模型泛化能力和过拟合现象(overfitting)的矛盾、以及其主要缓解方法正则化技术原理初探
1. 偏差与方差 - 机器学习算法泛化性能分析 在一个项目中,我们通过设计和训练得到了一个model,该model的泛化可能很好,也可能不尽如人意,其背后的决定因素是什么呢?或者说我们可以从哪些方面去 ...
- 深入理解java中的底层阻塞原理及实现
谈到阻塞,相信大家都不会陌生了.阻塞的应用场景真的多得不要不要的,比如 生产-消费模式,限流统计等等.什么 ArrayBlockingQueue, LinkedBlockingQueue, Delay ...
- KafkaConsumer 长时间地在poll(long )方法中阻塞
一,问题描述 搭建的用来测试的单节点Kafka集群(Zookeeper和Kafka Broker都在同一台Ubuntu上),在命令行下使用: ./bin/kafka-topics. --replica ...
- DisplayNameFor()方法的工作原理
DisplayNameFor()方法的工作原理原创Peter Yelnav 最后发布于2018-11-23 11:09:51 阅读数 1308 收藏展开最近研究了一下ASP.NET MVC,困惑于视图 ...
- JVM系列-方法调用的原理
JVM系列-方法调用的原理 最近重新看了一些JVM方面的笔记和资料,收获颇丰,尤其解决了长久以来心中关于JVM方法管理的一些疑问.下面介绍一下JVM中有关方法调用的知识. 目的 方法调用,目的是选择方 ...
- go-micro开发RPC服务的方法及其运行原理
go-micro是一个知名的golang微服务框架,最新版本是v4,这篇文章将介绍go-micro v4开发RPC服务的方法及其运作原理. 基本概念 go-micro有几个重要的概念,后边开发RPC服 ...
随机推荐
- Spring常用的接口和类(一)
一.ApplicationContextAware接口 当一个类需要获取ApplicationContext实例时,可以让该类实现ApplicationContextAware接口.代码展示如下: p ...
- Iphone和iPad适配, 横竖屏
竖屏情况下: [UIScreen mainScreen].bounds.size.width = 320 [UIScreen mainScreen].bounds.size.width = 568 横 ...
- HDU 1505 City Game (hdu1506 dp二维加强版)
F - City Game Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submi ...
- Floyd算法 及其运用
#include<stdio.h> ][]; ][]; void floyd(int n) { ;k<=n;k++) { ;i<=n;i++) { ;j<=n;j++) ...
- shell脚本步骤调试
第一种方式===> [root@localhost functions]# sh -x test.sh --check xx+ '[' --check '!=' -check ']'+ case ...
- jstack命令详解
jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使 ...
- hdu 1425 sort 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1425 常规的方法是对输入的数从大到小进行排序(可以用sort或qsort),然后输出前m大的数. 不过 ...
- 一个iOS图片选择器的DEMO(实现图片添加,宫格排列,图片长按删除,以及图片替换等功能)
在开发中,经常用到选择多张图片进行上传或作其他处理等等,以下DEMO满足了此功能中的大部分功能,可直接使用到项目中. 主要功能如下: 1,图片九宫格排列(可自动设置) 2,图片长按抖动(仿苹果软件删除 ...
- OSG addEventHandler W键 L键 F键
// add the state manipulator viewer->addEventHandler( new osgGA::StateSetManipulator(viewer-&g ...
- opencv学习笔记(五)镜像对称
opencv学习笔记(五)镜像对称 设图像的宽度为width,长度为height.(x,y)为变换后的坐标,(x0,y0)为原图像的坐标. 水平镜像变换: 代码实现: #include <ios ...