[转载]网络数据流的java处理
网络数据流的java处理
该文章对编写客户服务器应用的java程序员有所帮助,可以解决程序在对方出现故障的时候继续稳定运行.
前言:java程序要处理很多的网络数据,网络数据发送和接收以及数据流的处理是java程序要特别关注的方面,随着java的发展,这些方法也越来越得到重视和加强。本文从几个方面解释了java正确处理网络数据流的要素,这些也是java程序员必须了解的基本的知识。
1:庞大的java流处理
首先,之所以说java流的庞大,是因为java中的流处理比其他语言的流处理在内容上多的多。
java流在处理上分为字符流和字节流。字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。
Java内用Unicode编码存储字符,字符流处理类负责将外部的其他编码的字符流和java内Unicode字符流之间的转换。而类 InputStreamReader和OutputStreamWriter处理字符流和字节流的转换。字符流(一次可以处理一个缓冲区)一次操作比字节 流(一次一个字节)效率高。
对应不同的流,需要不同的流构建器或流过滤实现。java目前依然在逐渐增加其流处理方法,虽然java类库的创作人员可以列举出很多理由来说明这要做的优点,但我还是觉得java开始变得向其他语言一样复杂起来。
|
|
2:网络数据流的收发
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); |
这些方法总给人一种不太舒服的感觉。不过从Jdk1.4开始弥补了这一点。JDK1.4中新增加了新的I/O流处理,在缓冲区管理、可伸缩网络和文件 IO、字符集支持、正规表达式匹配方面做了新的处理。其中缓冲区管理和通道(Channel)概念则是对网络数据流的收发处理支持的强化。缓冲区管理中 ByteBuffer类更好的支持了网络数据流处理。在网络连接中,通道代表了sockets的连接。基于这些新的IO处理,以上代码可以改写为:
......ByteBuffer bytebuf = ByteBuffer.allocate(2048); // 创建一个指定大小的缓冲区InetSocketAddress isa = new InetSocketAddress(hostname,port);sc = SocketChannel.open(); // 建立一个socket通道sc.connect( isa); // 建立一个socket连接… sc.write(bytebuf); // 发送数据…sc.read(bytebuf); // 接收数据这样的程序似乎要流畅的多。 |
|
|
3:java对网络数据流的处理
java程序对网络数据流的处理要关注四个基本方面:数据流的编码,字节顺序,数据格式对应和取数。这是四个不同的问题,但是都影响到网络数据的正确接收。
3.1 网络数据流的解码和编码
网络数据流的编码和解码主要针对流中出现的字符串。网络数据流中的字符串均为原始的字节流形式。
要正确接收网络数据流中的字符串,首先要知道该字符串的编码方案。然后才可以调用解码的方法获得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");....... |
3.2 网络数据流的字节顺序
目 前的字节顺序有两类:BIG_ENGIAN和LITTLE_ENDIAN。各个平台所支持的字节序不同,例如AIX、Tru64Unix、Windows 等操作系统平台采用LITTLE_ENDIAN字节序,Solaris等操作系统平台采用BIG_ENGIAN。Java自身采用的是 BIG_ENGIAN字节序,当java和运行在其他平台上的其他语言编写的通信程序通信时,则必须考虑到数据的字节序。
Jkd1.4新增加的包NIO中的类ByteOrder则带来了一定的方便。针对从网络数据流的字节序,我们只要增加一行就可以轻松的处理字节序了:
bytebuf.order(ByteOrder.LITTLE_ENDIAN); //按照LITTLE_ENDIAN字节序收发数据
sc.read(bytebuf); // 接收数据
上面的方法虽然简化了我们的编程,但没有真正处理好分布式应用的网络数据字节序问题。例如,java同时和在Tru64Unix、Solaris平台上的 应用通信时,上述方法就不能解决问题。因为同一数据包,可能无法判断其字节序是那一种。此时要求网络数据包内携带附加的字节序信息显然是不现实的。这种情 况下,java语言需要提供对XDR(外部数据表达)的支持,目前XDR已经为事实上的网络数据流的标准格式,分布式应用的网络数据流基本都遵循了这种格 式,如果java语言提供了对XDR的支持,就可以解决通用性的问题。对于分布式应用中的网络数据流的处理就无需再根据其平台判断其字节序,只要按照 XDR格式进行处理就可以了。
3.3 网络数据流中数据格式的对应
C/C++语言编写的网络程序中一般采用数据结构的缓冲区发送数据,在java端接收数据时,会出现一些因数据组织引起的问题:
如结构 typedef struct {int id;char name[32];short val;float fval; } SendData |
在32位操作系统中,它的大小并不是42,而是44!数据的组织如下图所示:
当通过网络发送到客户端时,客户端也接收到44个字节,如果按照顺序依次取相应的值,则会发现最后取得的浮点值不正确。这是因为把短整型数据后没有意义的两位作为了浮点数中的其中两位。如果想正确接收该数据,则必须跳过短整型数据后没有意义的两位,再取浮点值。
而如果以上的结构变为:
typedef struct {int id;char name[32];float fval;short val; } |
则java端按照顺序依次接收数据就不会发生问题。
所以,在编写程序时,对数据的正确组织也是非常重要的。
3.4从网络数据流中取得需要的数据
在C/C ++的Socket编程时,采用数据结构收发数据很方便,特别是接收数据时,可以由数据结构的数据类型自动获得网络数据流相应的数据。但是在java中, 目前我们必须对流进行分析,逐一的取得自己所需要的数据,并且由于网络数据流是原始的数据流,还要根据程序所需要的数据类型对网络数据流进行解码处理。发 送网络数据时同样需要对数据进行封装。这个过程也增加了java程序的烦琐性。例如上述结构,要用如下代码获取相应数据:
- int id = bytebuf.getInt(); // 获得整数型值
- int limit = bytebuf.limit(); // 获得字节缓冲区的限值
- bytebuf.limit(36); // 设置字节缓冲区的限值,为字符串后面的第一个字节位置
- CharBuffer charbuf = decoder.decode(bytebuf); // 解码获得字符串
- Bytebuf.limit(limit); // 恢复字节缓冲区原来的限值
- float fval = bytebuf.getfloat(); // 获得浮点型值
- short val = bytebuf.getshort(); // 获得短整型数值
|
|
4:结束语
从上面的介绍可以看出,java程序中对网络数据流的处理涉及的问题较多。在编写网络程序时,必须注意这些问题,以使得程序正确的处理通信的内容。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130720/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/374079/viewspace-130720/
[转载]网络数据流的java处理相关推荐
- 黑马程序员_Java解析网络数据流的三种特殊方法
Java解析网络数据流的三种特殊方法 Java作为最开放的语言,已越来越受到网络程序员的青睐.但这一青睐族有着同样的经历--曾经都为网络上通信的Java数据格式而烦恼. 笔者也不例外,曾经为此而查阅了 ...
- 全连接层的输入和输出_理解Web应用程序的本质,网络数据流处理与基础网络连接...
前言 前面一篇文章,我从整个应用程序的整体以及跟运行环境的关系简单聊了一下我们现在常用的Spring框架的设计基础和原则,其中主要是控制反转和依赖注入,以及容器化编程等概念. 这里我不想去复述这些概念 ...
- vlc网络数据流接收处理分析
网络数据流接收处理分析 1.在input.c(src\input)文件中的主线程循环 Thread in charge of processing the network packets ...
- 菜鸟学习笔记:Java提升篇9(网络1——网络基础、Java网络编程)
菜鸟学习笔记:Java提升篇9(网络1--网络基础.Java网络编程) 网络基础 什么是计算机网络 OS七层模型 Java网络编程 InetAddress InetSocketAddress URL类 ...
- 五子棋网络对战 java实现
五子棋网络对战 java实现 最近期末考试,压力实在是太大了.专业不对口的痛苦,别人永远体会不来.闲暇之余,便想着巩固一下java的基础知识,以前看别人写的游戏,心里都觉得哇 好厉害啊,我什么时候才可 ...
- java网络编程是java开发吗,22年最新
凭借编程大牛最新版Java核心开发手册,掌握了能进阿里.面对市场需求缩水的时期,老关的朋友是如何拿到阿里offer的呢?别着急!今天就来分享一下我朋友的蜜拓蜜武器:阿里大牛整理的Java核心开发手 J ...
- 重庆大学java考试_重庆大学网络教育学院 《Java程序设计》形考一答案
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 重庆大学网络教育学院 <Java程序设计>形考一答案 786971758 一.单项选择题 (共 30 题.共 60 分)1. 给定程序如下 p ...
- 视频教程-网络聊天室Java基础版(Socket_Swing编程)仿QQ聊天-Java
网络聊天室Java基础版(Socket_Swing编程)仿QQ聊天 IT行业资深从业者,7年资深Java高级开发,Java架构师.曾就职银行.电信等行业多家上市公司.担任项目负责人,软件架构师.有丰富 ...
- java压缩传输gzip_服务器使用Gzip压缩数据,加快网络传输(Java 例子)
在我们的项目中,添加对gzip的支持,是为了加快数据在网络中的传输速度. 使用gzip,首先要设置请求消息头Accept-Encoding为gzip.这样,你将会得到一个响应,根据消息头Content ...
- 网络聊天室(Java)
摘要 本文阐述了基于Linux环境,Java语言实现的基本聊天室功能,涉及Linux下的Java 语言的Socket编程.以及Java语言的多线程编程. 关键字 Linux Java ...
最新文章
- python线程,进程,协程
- 无向图求桥 UVA 796
- 神经网络实现xor_在神经网络中实现逻辑门和XOR解决方案
- LG将授权webOS给其他电视厂商使用
- 模板上 php dede,DEDE模板中使用php和if判断语句实例
- 关于pc和移动端相同网站的不同url跳转问题
- react中对props.children进行操作
- 并发编程学习之生产者消费者模式 - 使用Condition实现
- 新手必看——JAVA排序详解(冒泡排序和插入排序)
- WPS Excel快捷键
- 《如何阅读一本书》读书笔记
- VSPD虚拟串口工具——使用完一定要删除串口
- win10打开语言服务器,在 Windows 10 中,部署一个 Go 1.13 语言的本地文档浏览 web 服务器的流程(已缺少 godoc.exe)...
- 用了十年竟然都不对,Java、Rust、Go主流编程语言的哈希表比较
- CentOS7 yum方式安装MySQL 5.7
- linux配置网卡、修改主机名和映射文件(手把手配置)
- Red_Hat_Linux忘记root密码解决办法
- 一亩三分地(1point3acres)每日答题记录
- 如何封禁IP和IP段 看完这篇我会了
- 什么是数字化转型、数字经济?