现在的位置: 首页 > 综合 > 正文

Java中的分包处理 

2018年05月03日 ⁄ 综合 ⁄ 共 1790字 ⁄ 字号 评论关闭

java中的分包处理 

一般在socket处理大数据量传输的时候会产生粘包和半包问题,有的时候tcp为了提高效率会缓冲N个包后再一起发出去,这个与缓存和网络有关系。接收端接收到正确的后都要给发送端一个应答。不给应答的算超时,发送端将重发。 出现粘包和半包现象,是因为TCP当中,只有流的概念,没有包的概念.。
可以使用UDP协议.这样可以就可以区分每个包了.但是要确保包的丢失处理.为了提到效率,可以考虑写一个滑动窗口进行收发包.
若采用TCP协议进行传输,就要将每个包区分开来.可以有三种方式.因为TCP是面向流的.流只有打开和关闭,你要用一个流传输多个包,那就要向办法区分出每个包.

1.可以每次发送同样大小的包,过大的包不予发送,过小的包,后面部分用固定的字符'/0'进行填充。

2. 将流按字符处理,抽出一个字符做转义字符(通常Java用'/'来做转义字符,比如"/n"表示换行).假如就设'/'为转义字符,发送方如果流当中出现'/',就在后面在追加一个'/',如果包结束,则用'/'做包的结束符.这样,在接收方,若读取一个单独的'/'或者流结束,就标示前面的内容构成一个包,如果连续读取两个'/',就将两个'/'用一个'/'进行替换.这样,就可以保证原来包中的信息不变,同时也能区分出每个包了。

3.在发送方发送一个包的时候,先将这个包的长度发送给对方(一般是4个字节表示包长),然后再将包的内容发送过去.接收方先接收4个字节,看看包的长度,然后按照长度来接收包,最好是大端字节序。

以上三种方法,是网络传输中经常用到的方法.后两种很常见.最后一种,在TCP长连接传输中应用最多.
综合以上的说法,就是要在TCP协议以上再封装一层协议,用来做分包的信息交换.
当然,如果TCP不是非要长连接,或者,信息包不是批量传输的情况下.可以一次TCP连接只传输一个包.这种情况下一般,一次TCP完成一次交互,即发送方发送信息包,接收方接收信息包同时发送一个接收方的响应包给发送方,表明接收方收到信息包,还是收到了错误包,或者接收方系统异常没有处理这个包之类的信息. 其实HTTP的交互过程,就是这样的.

 

读取数据使用DataInputStream和DataOutputStream,不要用BufferedReader和PrintStream。使用字节传送方式,使用readFully,
readFully
public final void readFully(byte[] b)
                     throws IOException参见 DataInput 的 readFully 方法的常规协定。
从所包含的输入流中读取此操作需要的字节。

指定者:
接口 DataInput 中的 readFully
参数:
b - 存储读取数据的缓冲区。
抛出:
EOFException - 如果此输入流在读取所有字节之前到达末尾。
IOException - 如果发生 I/O 错误。
另请参见:
FilterInputStream.in

--------------------------------------------------------------------------------

readFully
public final void readFully(byte[] b,
                            int off,
                            int len)
                     throws IOException参见 DataInput 的 readFully 方法的常规协定。
从所包含的输入流中读取此操作需要的字节。

指定者:
接口 DataInput 中的 readFully
参数:
b - 存储读取数据的缓冲区。
off - 数据的起始偏移量。
len - 要读取的字节数。
抛出:
EOFException - 如果此输入流在读取所有字节之前到达末尾。
IOException - 如果发生 I/O 错误。
另请参见:
FilterInputStream.in
 
 
Java code

in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
out = new DataOutputStream(socket.getOutputStream());

抱歉!评论已关闭.