今天自己实现了下TCP处理粘包的问题

用的是netty 的TCP服务框架 具体代码实现


package com.tongfang.forward.server.handler;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class MyTcpHandler extends ChannelHandlerAdapter {


static int count = 1;
byte[] bigdata=new byte[0];
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof ByteBuf) {
ByteBuf data = (ByteBuf) msg;
int bytes = data.readableBytes();
byte[] temp = new byte[bytes];
data.readBytes(temp);
//将读取到的字节保存
bigdata = combineByteArray(bigdata,temp);
//如果不满足协议最少4个字节的话就不处理
if(bigdata.length< 4){
System.out.println("不满足协议要求最少4个字节");
return;
}
//我这边定义的协议头是4个字节
byte[] lengByte = new byte[4];
System.arraycopy(bigdata, 0, lengByte, 0, 4);
//获取内容长度
int length = bytesToInt(lengByte);
System.out.println("协议长度为:"+length);
if(length > bigdata.length){
System.out.println("不满足协议长度要求要求");
return;
}
//判断获取到的数据能解析出来几个
int j = bigdata.length%(length+4)>0?bigdata.length/(length+4)-1:bigdata.length/(length+4);
for(int i= 0; i < j; i++){
byte[] head = new byte[4];
//获取长度
System.arraycopy(bigdata, 0, head, 0, 4);
int tempLength = bytesToInt(head);
byte[] temp2 = new byte[tempLength];
//获取内容
System.arraycopy(bigdata, 4, temp2, 0, tempLength);
String body = new String(temp2, "UTF-8");
export(body,count);
//去掉内容
bigdata = copyNewAry(bigdata,tempLength+4,bigdata.length-tempLength-4);
count++;
}

}
}


public void export(String str,int count){

FileWriter fw = null;
try {
File f=new File("E:\\data"+count+".txt");

if(!f.exists()){
f.createNewFile();
}
fw = new FileWriter(f, true);
PrintWriter pw = new PrintWriter(fw);
pw.println(str);
pw.flush();
fw.flush();
pw.close();
fw.close();
System.out.println("写入完成···");
} catch (IOException e) {
e.printStackTrace();
}

}

private byte[] copyNewAry(byte[] array,int start,int length){
byte[] newAry = new byte[length];
System.arraycopy(array, start, newAry, 0, newAry.length);
return newAry;
}





private static byte[] combineByteArray(byte[] array1, byte[] array2) {
byte[] combined = new byte[array1.length + array2.length];
System.arraycopy(array1, 0, combined, 0, array1.length);
System.arraycopy(array2, 0, combined, array1.length, array2.length);
return combined;
}

public int bytesToInt(byte[] bArr) {
if(bArr.length!=4){
return -1;
}
return (int) ((((bArr[0] & 0xff) << 24)
| ((bArr[1] & 0xff) << 16)
| ((bArr[2] & 0xff) << 8)
| ((bArr[3] & 0xff) << 0)));
}

public static void main(String[] args) {
System.out.println(1024%252);
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity实现Socket通讯时,常常会遇到TCP粘包和拆包的问题。下面我将介绍在Unity中如何解决这些问题TCP粘包是指在传输过程中,由于数据缓冲区的限制,多个小的数据包可能会被合并成一个大的数据包,导致数据的解析和处理出现问题。为了解决这个问题,可以通过以下两种方式来处理。 第一种方式是定长包头+包体的设计。即在数据包前面添加一个固定长度的包头,包头中包含了包体的长度信息。接收方在接收数据时,首先读取包头的长度信息,然后再根据长度信息读取相应长度的数据进行解析和处理。 第二种方式是使用特殊的字符序列作为包的分隔符。例如,在每个数据包的末尾添加一个换行符或其他不常用的字符作为分隔符。接收方在接收数据时,通过查找这个分隔符来确定包的结束位置,然后对数据进行解析和处理TCP拆包是指在传输过程中,一个大的数据包可能会被拆分成多个小的数据包,导致数据的解析和处理出现问题。为了解决这个问题,可以通过以下方式来处理。 可以在接收方使用缓冲区来接收数据,并且设置一个最大接收长度。当接收到的数据长度小于最大接收长度时,将数据放入缓冲区中,并在缓冲区中进行数据的拼接。当接收到的数据长度大于等于最大接收长度时,对缓冲区中的数据进行解析和处理,并清空缓冲区。 以上是Unity实现Socket通讯时解决TCP粘包和拆包问题的方法。希望对你有帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值