`

从Socket中读取指定长度数据问题

阅读更多

InputStream is = .....
...................
byte[] bs = new byte[10];
int readed = is.read(bs);
is.close();
我们知道上面的代码可以从输入流里读取readed个字节的数据(readed范围为-1到10),readed==-1表示流已读完,那么什么时候会出现readed为0-9的情况呢?
答案:输入流中剩余内容不足10个字节(如is为FileInputStream表示文件剩余内容不足10个字节)

但对于套接字读取我们要注意,代码如下:

InputStream is = socket.getInputStream();
is.read...
....
byte[] bs = new byte[10];
is.read(bs);
String A=new String(bs);
byte[] bs2 = new byte[60];
is.read(bs2);
String B=new String(bs2);
上面对例子表示从套接字中接收数据,先接收10个字节的字段A,然后再接收60个字节的字段B,但实际is.read(bs)却有可能读取的数据不足10个字节,从而导致is.read(bs2)的时候却读到了字段A的一部分数据,这样就出错了,所以理论上上面这种写法是不正确不严谨的(小数据时也许在大多数情况下没问题,但不能保证一定没问题)。

对于套接字读取需要这样写:
// 从套接字缓冲区is中读取length长度的数据
private byte[] recvBytes(InputStream is, int length) throws IOException {
int tmpLength = 512; // 每次读取最大缓冲区大小
byte[] ret = new byte[length];
int readed = 0, offset = 0, left = length;
byte[] bs = new byte[tmpLength];
while (left > 0) {
try {
readed = is.read(bs, 0, Math.min(tmpLength, left));
if (readed == -1)
break;
System.arraycopy(bs, 0, ret, offset, readed);
} finally {
offset += readed;
left -= readed;
}
}
return ret;
}
byte[] bs = recvBytes(is, 10);
byte[] bs2 = recvBytes(is, 60);


分享到:
评论

相关推荐

    netty websocket通讯接收数据不完整问题

    这是一个java web项目集成了netty websocket的...初始化握手对象时指定了maxFramePayloadLength 的长度、以及通过配置netty内置解码器处理数据半包等方法,均无效。以下是终极解决办法,供大家参考和解决这样的问题。

    基于流模式长连接的简单实现

    基于流模式的下,数据一直在发送,我们需要知道,每次发送数据量,所以常见的方式时,我们在发送数据时,指定此次发送数据的长度,服务器读取流数据时,先读取数据长度,然后再按长度读取此次发送的数据。...

    UDP单播 、组播、广播,使用Qt实现,工程文件包,下载解压缩直接导入工程即可

    UDP是轻量的、不可靠的、面向数据报、无连接的协议,它可以用于对可靠性要求不高的场合,和TCP通信不同,两个程序之间进行UDP通信无需预先建立持久的socket连接,UDP每次发送数据报都需要指定目标地址和端口。...

    通讯调试工具,支持:串口通讯、串口代理、TCP、UDP、Telnet、Ping、TFtp等通讯测试

    2、支持动态命令,如命令中含有帧长度、校验等数据项目,命令可以进行分组,由树形控件管理。方法上采用 Lua脚本语言进行扩展,扩展的界面内容包含终端窗口的右键菜单、脚本窗口的按钮事件、扩展的树命令; 3、支持...

    PHP程序开发范例宝典III

    实例160 清空指定数据表中的指定数据 245 实例161 批量清空数据表 246 6.8 MYSQL数据库的备份 248 实例162 通过命令模式备份数据库 248 实例163 通过phpMyAdmin备份数据库 249 实例164 通过手动方式备份...

    java jdk实列宝典 光盘源代码

    读写Blob数据,blob数据常以二进制形式存储比较大的文件数据,如图片、视频文件等,本文介绍如何往数据库中读写blob数据,BlobData.java; 使用ResultSet更新数据库,UpdateWithResultSet.java; 使用RowSet,....

    C#全能速查宝典

    1.1.18 ReadLine方法——从当前流中读取一行字符 20 1.1.19 typeof运算符——获得系统原型对象的类型 21 1.1.20 using关键字——引入命名空间 22 1.1.21 WriteLine方法——写入流 23 1.2 数学方法类——Math 25 ...

    标准MFC WinSock ActiveX控件开发实例(II)高级篇

    if(len)//如果读取数据的长度小于传入的长度,将传入的长度更改为实际长度 gDataMaxLength = len; switch(Data->vt) { case VT_BSTR://按字符串形式接收 buffer[gDataMaxLength] = '\0'; Data->...

    mysql数据库my.cnf配置文件

    # 如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程, # 增加这个值可以改善系统性能.通过比较Connections和Threads_created状态的变量,...

    flex3的cookbook书籍完整版dpf(包含目录)

    从共享对象中读取数据 17.5节. 删除共享对象中的数据 17.6节. 序列化类型对象 17.7节. 在多个应用程序中访问同一个共享对象 17.8节. 记住用户输入文本框的内容 第十八章. 数据服务和服务端通信(574) 18.1节. 配置...

    Python核心编程第二版(ok)

     6.8.7 从现实中得来的教训   6.8.8 Python的Unicode支持   6.9 相关模块   6.10 字符串关键点总结  6.11 列表   6.12 操作符   6.12.1 标准类型操作符   6.12.2 序列类型操作符   6.12.3 ...

    易语言程序免安装版下载

    易语言5.1 相对于易语言5.0更新说明: ... 修改XML解析支持库,增加写出CDATA数据功能,解决解析XML时错误的丢弃换行和TAB字符的BUG,解决读取节点值时对CDATA数据进行转义处理的BUG。 20. 修改扩展界面支持库...

    c# 加密和解密相关代码

    offset 字节数组中的偏移量,从该位置开始使用数据 count 数组中用作数据的字节数 返回值 计算所得的哈希代码 说明:本实例用到了ComputeHash 方法的第一种重载形式。 设 计过程 (1)打开Visual Studio 2008 开发...

    《你必须知道的495个C语言问题》

    《你必须知道的495个C语言问题》以问答的形式组织内容,讨论了学习或使用C语言的过程中经常遇到的一些问题。书中列出了C用户经常问的400多个经典问题,涵盖了初始化、数组、指针、字符串、内存分配、库函数、C预...

    你必须知道的495个C语言问题

    1.8 如何在C中实现不透明(抽象)数据类型? 1.9 如何生成“半全局变量”,就是那种只能被部分源文件中的部分函数访问的变量? 存储类型 1.10 同一个静态(static)函数或变量的所有声明都必需包含static存储类型...

Global site tag (gtag.js) - Google Analytics