java中处理socket通信过程中粘包的情况
时间:2019-03-30
本文章向大家介绍java中处理socket通信过程中粘包的情况,主要包括java中处理socket通信过程中粘包的情况使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
这两天学习了java中处理socket通信过程中粘包的情况,而且很重要,所以,今天添加一点小笔记。
处理粘包程序是客户端的接受消息线程:
客户端:
import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.Reader; import java.net.Socket; import java.nio.CharBuffer; public class TestSocketClient { public static void main(String[] args) { // TODO Auto-generated method stub new TestSocketClient().start(); } class SendThread extends Thread{ private Socket socket; public SendThread(Socket socket){ this.socket=socket; } @Override public void run(){ while(true){ try{ Thread.sleep(1000); String send="<SOAP-ENV:Envelope>"+System.currentTimeMillis()+"</SOAP-ENV:Envelope>"; PrintWriter pw=new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); pw.write(send); pw.flush(); }catch(Exception e){ e.printStackTrace(); } } } } class ReceiveThread extends Thread{ private Socket socket; private volatile byte[] bytes=new byte[0]; public ReceiveThread(Socket socket){ this.socket=socket; } public byte[] mergebyte(byte[] a,byte[] b,int begin,int end){ byte[] add=new byte[a.length+end-begin]; int i=0; for(i=0;i<a.length;i++){ add[i]=a[i]; } for(int k=begin;k<end;k++,i++){ add[i]=b[k]; } return add; } @Override public void run(){ while(true){ try{ InputStream reader=socket.getInputStream(); if(bytes.length<2){ byte[] head=new byte[2-bytes.length]; int couter=reader.read(head); if(couter<0){ continue; } bytes=mergebyte(bytes,head,0,couter); if(couter<2){ continue; } } //下面这个值请注意,一定要取2长度的字节子数组作为报文长度,你懂得 byte[] temp=new byte[0]; temp=mergebyte(temp,bytes,0,2); String templength=new String(temp); int bodylength=Integer.parseInt(templength); if(bytes.length-2<bodylength){ byte[] body=new byte[bodylength+2-bytes.length]; int couter=reader.read(body); if(couter<0){ continue; } bytes=mergebyte(bytes,body,0,couter); if(couter<body.length){ continue; } } byte[] body=new byte[0]; body=mergebyte(body, bytes, 2, bytes.length); System.out.println("client receive body: "+new String(body)); bytes=new byte[0]; }catch(Exception e){ e.printStackTrace(); } } } } public void start(){ try{ Socket socket=new Socket("127.0.0.1",18889); new SendThread(socket).start(); new ReceiveThread(socket).start(); }catch(Exception e){ e.printStackTrace(); } } }
服务端:
package com.meituan.service.bankgate.gateway; /** * Created by cqx on 16/7/19. */ import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.nio.CharBuffer; import java.util.Date; public class TESTAHAHHA { private final static String SOAP_BEGIN = "<SOAP-ENV:Envelope"; private final static String SOAP_END = "</SOAP-ENV:Envelope>"; public static void main(String[] args) { // TODO Auto-generated method stub TESTAHAHHA testserver=new TESTAHAHHA(); testserver.start(); } public void start(){ try{ ServerSocket serversocket=new ServerSocket(18889); while(true){ Socket socket=serversocket.accept(); new SocketThread(socket).start(); } }catch(Exception e){ e.printStackTrace(); } } class SocketThread extends Thread{ private Socket socket; private String temp; public SocketThread(Socket socket){ this.socket=socket; } public Socket getsocket(){ return this.socket; } public void setsocjet(Socket socket){ this.socket=socket; } @Override public void run(){ try{ Reader reader=new InputStreamReader(socket.getInputStream()); // Writer writer=new PrintWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8")); OutputStream writer=socket.getOutputStream(); CharBuffer charbuffer=CharBuffer.allocate(8192); int readindex=-1; while((readindex=reader.read(charbuffer))!=-1){ charbuffer.flip(); temp+=charbuffer.toString(); if(temp.indexOf(SOAP_BEGIN)!=-1 && temp.indexOf(SOAP_END)!=-1){ //System.out.println(new Date().toLocaleString()+"server:"+temp); temp=""; String str="receive the soap message hahahah"; byte[] headbytes=str.getBytes(); int length=headbytes.length; String l=String.valueOf(length); byte[] lengthbytes=l.getBytes(); byte[] bytes=new byte[length+lengthbytes.length]; int i=0; for(i=0;i<lengthbytes.length;i++){ bytes[i]=lengthbytes[i]; } for(int j=i,k=0;k<length;k++,j++){ bytes[j]=headbytes[k]; } System.out.println("server send:"+new String(bytes)); writer.write(bytes); writer.flush(); }else if(temp.indexOf(SOAP_BEGIN)!=-1){ temp=temp.substring(temp.indexOf(SOAP_BEGIN)); } if(temp.length()>1024*16){ break; } } }catch(Exception e){ e.printStackTrace(); }finally{ if(socket!=null){ try{ if(!socket.isClosed()){ socket.close(); } }catch(Exception e){ e.printStackTrace(); } } } } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
- 来腾讯云开发者实验室学习.NET
- 跨域资源共享(CORS)在ASP.NET Web API中是如何实现的?
- 使用腾讯云 GPU 学习深度学习系列之六:物体的识别与定位
- npm5 新版功能特性解析及与 yarn 评测对比
- H5直播避坑指南
- 龙门阵之 DevOps 门外汉须知
- 全面进阶 H5 直播(上)
- 这年头,不会斗图都毕不了业?
- 龙妈也会死?《权力的游戏》 AI 算法预测丹妮女王危在旦夕
- 腾讯云 GAME-TECH 沙龙干货回顾:海外网络拓展及质量把控
- 通过扩展让ASP.NET Web API支持W3C的CORS规范
- 腾讯云GAME-TECH沙龙干货回顾:腾讯游戏云全球化实践
- 腾讯云GAME-TECH沙龙干货回顾:猎豹游戏出海经验分享
- 腾讯云GAME-TECH沙龙干货回顾:绿洲全球化案例分享
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- ubuntu16.04 升级内核的方法步骤
- Android 列表倒计时的实现的示例代码(CountDownTimer)
- Android 控件设置阴影效果
- 解决VScode配置远程调试Linux程序的问题
- Android EasyBarrage实现轻量级弹幕效果
- android 获取本机其他app的版本信息的示例代码
- android相册选择图片的编码实现代码
- ClickHouse和他的朋友们(2)MySQL Protocol和Read调用栈
- Android图片三级缓存的原理及其实现
- Android TextView实现带链接文字事件监听的三种常用方式示例
- Android ViewDragHelper使用介绍
- Android语音声波控件 Android条形波控件
- Ubuntu下安装CUDA10.0以及问题
- Android ListView实现单选及多选等功能示例
- Recyclerview添加头布局和尾布局、item点击事件详解