本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告

戒除浮躁,读好书,交益友


我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:邢红瑞的blog
日志总数:523
评论数量:1142
留言数量:0
访问次数:9692432
建立时间:2004年12月20日




[java语言]java中的分包处理 
原创空间,  软件技术,  电脑与网络

邢红瑞 发表于 2009/3/10 18:02:05

  一般在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,readFullypublic final void readFully(byte[] b)                     throws IOException参见 DataInput 的 readFully 方法的常规协定。 从所包含的输入流中读取此操作需要的字节。 指定者:接口 DataInput 中的 readFully参数:b - 存储读取数据的缓冲区。 抛出: EOFException - 如果此输入流在读取所有字节之前到达末尾。 IOException - 如果发生 I/O 错误。另请参见:FilterInputStream.in -------------------------------------------------------------------------------- readFullypublic 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());


阅读全文(4078) | 回复(2) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.328 second(s), page refreshed 144759203 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号