java怎么处理socket服务端粘包

Python016

java怎么处理socket服务端粘包,第1张

socket粘包是避免不了的,主要在于接收方如何解包和控制。处理方法:

定制socket传输协议。增加包头、命令、数据长度、数据体、结束位。比如发送消息:,

String msg = "你好"

byte[] byBuffer = msg.getBytes()

//加入定制的协议该条数据位:

byte[] b = new byte[4+byBuffer.length]

b[0] = 0xFFFFF//随便定义,包头

b[1] = 0x01//命令

b[2] = byBuffer.length//数据长度

b[3 - n] = byBuffer//数据

b[b.length -1] = 0x0d//结束

接收方接收到该数据后判断包头是否一致,不一致则不要,根据b[2]数据长度来去数据,第一次未接收完继续接收第二次,直到接收数据长度==b[2]为止。一条完整的数据就出来了。

写得很随意,理解理解~

try

{

InputStream is = socket.getInputStream()

while(running)

{

/*

* 读取消息长度

*/

byte[] totalLen = new byte[4]

int readLen = 0//本次读取的字节数

int position = 0//已经读取数据的下一个位置

while((readLen=is.read(totalLen,position,(4-position)))>=0)

{

position = position + readLen

if(position==4)

{

break

}

}

if(readLen<0)

{//读取到EOF,socket已close或reset

throw new SocketException("读取数据流结尾.")

}

int length = SGIP.byteArrayToInt(totalLen)

ByteBuffer mesg = ByteBuffer.allocate(length)

mesg.order(SGIP.getByteOrder())

mesg.put(totalLen)

//读取所有消息

readLen = 0

position = mesg.position()

while((readLen=is.read(mesg.array(), position, mesg.remaining()))>=0)

{

position = position + readLen

mesg.position(position)

if(mesg.remaining()==0)

{

break

}

}

if(readLen<0)

{//读取到EOF,socket已close或reset

throw new SocketException("读取数据流结尾.")

}

mesg.position(0)

//解析消息

mesg.order(ByteOrder.BIG_ENDIAN)

try

{

//解析mesg

}

catch (Exception e)

{

logger.error("语法错误出错,无法解析",e)

//接收到非法命令,断开连接

socket.close()

break

}

logger.debug(this.getName()+"退出")

应该没有这样严重的。 TCP只有在网络很差的情况下会有些数据丢掉的。 你在局域网应该还不至于俄。

多办是没有处理粘包俄。人家还没有把数据发给你就读取了。读到就会是 00

定协议把。 很简单的俄。 如 包头+数据区域的长度+数据。

这样根据长度来解析数据就不会出现粘包了。