知识大全 网络数据流的java处理

Posted 字节

篇首语:大鹏一日同风起,扶摇直上九万里。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 网络数据流的java处理相关的知识,希望对你有一定的参考价值。

  郭洪锋 ()该文章对编写客户服务器应用的java程序员有所帮助 可以解决程序在对方出现故障的时候继续稳定运行   前言 java程序要处理很多的网络数据 网络数据发送和接收以及数据流的处理是java程序要特别关注的方面 随着java的发展 这些方法也越来越得到重视和加强 本文从几个方面解释了java正确处理网络数据流的要素 这些也是java程序员必须了解的基本的知识      庞大的java流处理   首先 之所以说java流的庞大 是因为java中的流处理比其他语言的流处理在内容上多的多     java流在处理上分为字符流和字节流 字符流处理的单元为 个字节的Unicode字符 分别操作字符 字符数组或字符串 而字节流处理单元为 个字节 操作字节和字节数组     Java内用Unicode编码存储字符 字符流处理类负责将外部的其他编码的字符流和java内Unicode字符流之间的转换 而类InputStreamReader和OutputStreamWriter处理字符流和字节流的转换 字符流(一次可以处理一个缓冲区)一次操作比字节流(一次一个字节)效率高     对应不同的流 需要不同的流构建器或流过滤实现 java目前依然在逐渐增加其流处理方法 虽然java类库的创作人员可以列举出很多理由来说明这要做的优点 但我还是觉得java开始变得向其他语言一样复杂起来      网络数据流的收发   java对网络数据的发送和接收处理 也借用了一般流处理的方法 我们知道 在几乎其他所有语言中 网络数据的收发在利用类似send(或write)和recv(或read)的方法时并没有明显的流处理 但是java和这些语言的收发方法有较大区别 要借助流才可以完成         sock = new Socket(addr port);     OutputStream os = sock getOutputStream();     InputStream is = sock getInputStream();     os write(byte[] b);     is read(byte[] b);        这些方法总给人一种不太舒服的感觉 不过从Jdk 开始弥补了这一点 JDK 中新增加了新的I/O流处理 在缓冲区管理 可伸缩网络和文件IO 字符集支持 正规表达式匹配方面做了新的处理 其中缓冲区管理和通道(Channel)概念则是对网络数据流的收发处理支持的强化 缓冲区管理中ByteBuffer类更好的支持了网络数据流处理 在网络连接中 通道代表了sockets的连接 基于这些新的IO处理 以上代码可以改写为      ByteBuffer bytebuf = ByteBuffer allocate( ); // 创建一个指定大小的缓冲区    InetSocketAddress isa = new InetSocketAddress(hostname port);    sc = SocketChannel open(); // 建立一个socket通道    nnect( isa); // 建立一个socket连接    …     sc write(bytebuf); // 发送数据    …    sc read(bytebuf); // 接收数据    这样的程序似乎要流畅的多          java对网络数据流的处理   java程序对网络数据流的处理要关注四个基本方面 数据流的编码 字节顺序 数据格式对应和取数 这是四个不同的问题 但是都影响到网络数据的正确接收      网络数据流的解码和编码   网络数据流的编码和解码主要针对流中出现的字符串 网络数据流中的字符串均为原始的字节流形式     要正确接收网络数据流中的字符串 首先要知道该字符串的编码方案 然后才可以调用解码的方法获得java能够认识的Unicode编码字符串 可以用如下代码处理网络数据流中字符串的编码和解码   // 获得编码对象 即网络对等方的认识的字符串编码     Charset charset = Charset forName( ??? ); // ???为对等方的编码名 java必须支持     // 生成编码器和解码器对象     CharsetDecoder decoder = charset newDecoder();    CharsetEncoder encoder = charset newEncoder();         // 对从网络数据流中获得的字节流解码取得java字符串    CharBuffer charbuf = decoder decode(bytebuff);         // 将java字符串编码成指定编码的字节流 以便网络发送    Bytebuff bytebuff = encoder encode(CharBuffer wrap( Test String );                网络数据流的字节顺序   目前的字节顺序有两类 BIG_ENGIAN和LITTLE_ENDIAN 各个平台所支持的字节序不同 例如AIX Tru Unix Windows等操作系统平台采用LITTLE_ENDIAN字节序 Solaris等操作系统平台采用BIG_ENGIAN Java自身采用的是BIG_ENGIAN字节序 当java和运行在其他平台上的其他语言编写的通信程序通信时 则必须考虑到数据的字节序     Jkd 新增加的包NIO中的类ByteOrder则带来了一定的方便 针对从网络数据流的字节序 我们只要增加一行就可以轻松的处理字节序了   bytebuf order(ByteOrder LITTLE_ENDIAN); //按照LITTLE_ENDIAN字节序收发数据  sc read(bytebuf); // 接收数据    上面的方法虽然简化了我们的编程 但没有真正处理好分布式应用的网络数据字节序问题 例如 java同时和在Tru Unix Solaris平台上的应用通信时 上述方法就不能解决问题 因为同一数据包 可能无法判断其字节序是那一种 此时要求网络数据包内携带附加的字节序信息显然是不现实的 这种情况下 java语言需要提供对XDR(外部数据表达)的支持 目前XDR已经为事实上的网络数据流的标准格式 分布式应用的网络数据流基本都遵循了这种格式 如果java语言提供了对XDR的支持 就可以解决通用性的问题 对于分布式应用中的网络数据流的处理就无需再根据其平台判断其字节序 只要按照XDR格式进行处理就可以了      网络数据流中数据格式的对应   C/C++语言编写的网络程序中一般采用数据结构的缓冲区发送数据 在java端接收数据时 会出现一些因数据组织引起的问题 如结构 typedef struct     int  id;    char name[ ];    short val;    float fval;     SendData    在 位操作系统中 它的大小并不是 而是 !数据的组织如下图所示      当通过网络发送到客户端时 客户端也接收到 个字节 如果按照顺序依次取相应的值 则会发现最后取得的浮点值不正确 这是因为把短整型数据后没有意义的两位作为了浮点数中的其中两位 如果想正确接收该数据 则必须跳过短整型数据后没有意义的两位 再取浮点值     而如果以上的结构变为   typedef struct     int  id;    char name[ ];    float fval;    short val;         则java端按照顺序依次接收数据就不会发生问题     所以 在编写程序时 对数据的正确组织也是非常重要的      从网络数据流中取得需要的数据   在C/C++的Socket编程时 采用数据结构收发数据很方便 特别是接收数据时 可以由数据结构的数据类型自动获得网络数据流相应的数据 但是在java中 目前我们必须对流进行分析 逐一的取得自己所需要的数据 并且由于网络数据流是原始的数据流 还要根据程序所需要的数据类型对网络数据流进行解码处理 发送网络数据时同样需要对数据进行封装 这个过程也增加了java程序的烦琐性 例如上述结构 要用如下代码获取相应数据     int id = bytebuf getInt(); // 获得整数型值   int limit = bytebuf limit(); // 获得字节缓冲区的限值   bytebuf limit( ); // 设置字节缓冲区的限值 为字符串后面的第一个字节位置   CharBuffer charbuf = decoder decode(bytebuf); // 解码获得字符串   Bytebuf limit(limit); // 恢复字节缓冲区原来的限值   float fval = bytebuf getfloat(); // 获得浮点型值   short val = bytebuf getshort(); // 获得短整型数值    结束语   从上面的介绍可以看出 java程序中对网络数据流的处理涉及的问题较多 在编写网络程序时 必须注意这些问题 以使得程序正确的处理通信的内容     参考资料          关于作者   郭洪锋 在烟台东方电子信息产业集团公司中心所工作 一直从事分布式系统的开发和研究 cha138/Article/program/Java/hx/201311/27197

相关参考

知识大全 Java获取网络文件并插入数据库

Java获取网络文件并插入数据库  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  抓取各大网站的数

知识大全 Java网络编程 多种多样的连接数据库的方式

Java网络编程多种多样的连接数据库的方式  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一通过

知识大全 Java线程模型如何完善相关的数据处理

Java线程模型如何完善相关的数据处理  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java线

知识大全 Java在处理大数据的时候一些小技巧

Java在处理大数据的时候一些小技巧  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  众所周知ja

下列网络技术中,不属于数据安全技术的是

下列网络技术中,不属于数据安全技术的是_____。A、网络防火墙B、数字媒体技术C、数字签名技术D、数字水印技术答案:B解析:数字媒体技术主要包含场景设计、角色形象设计、游戏程序设计、多媒体后期处理、

知识大全 Java Socket常见异常处理

JavaSocket常见异常处理  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在java网络编

知识大全 Java趣味Java网络机器人

Java趣味Java网络机器人  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  packageau

知识大全 Java 网络编程

Java网络编程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  网络编程作为Java的主要应用之

知识大全 Java学习---网络编程

Java学习---网络编程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  网络模型OSI的网络模

知识大全 Java网络编程-Java Socket编程(五)

Java网络编程-JavaSocket编程(五)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!