socket 分包和组包:建议使用字节流。组包和拆包是一个近似序列化和反序列化的过程。
目录
消息形式为: 包长度(short)+包头(short)+messages(string)+包尾(short)
组包
组包的意思是按照协议构建二进制数组数据。
private void writesMessage(short cmd , String messages, short move,Socket socket) {
initOutput();
try {
output.writeShort(cmd);
output.writeChars(messages);
output.writeShort(move);
MyUtil.sendMessage(socket, byteOutput.toByteArray());
} catch (Exception e) {
e.printStackTrace();
}
}
private void initOutput()
{
byteOutput = new ByteArrayOutputStream();
output = new DataOutputStream(byteOutput);
}
/**
* 发送数据到网络流
*
* @param socket
* @param bytes
* @throws Exception
*/
public static void sendMessage(Socket socket, byte[] bytes)throws Exception {
DataOutputStream dataOutput = new DataOutputStream(socket.getOutputStream());
// 编写数据的长度
dataOutput.writeShort(bytes.length);
dataOutput.write(bytes);
dataOutput.flush();
}
拆包
按照协议将二进制数组数据解析为对应的字段。
short len = br.readShort();//br 为DataInputStream
short cmd = br.readShort();
byte[] bytes = new byte[len];
br.read(bytes, 0, len-4);
String messgeString = new String(bytes);
System.out.println("首条消息:"+messgeString);
short move = br.readShort();
C++组包发送与拼包解析
BYTE m_Buffer[100000];
int m_iLen=0;
void RecvTCP(const char * pBuffer, int iLen)
{
memcpy(m_Buffer + m_iLen, pBuffer, iLen);
int length = iLen + m_iLen;
int nPackage = length / 1008;
for (int i = 0; i < nPackage;i++)
{
//处理…
}
m_iLen = length - 1008 * nPackage;
memcpy(m_Buffer, m_Buffer + nPackage * 1008, m_iLen);
}
组包拆包示例
【Java TCP/IP Socket】构建和解析自定义协议消息(含代码)
自定义Udp/Tcp协议,通信协议Socket/WebSocket,IM粘包、分包解决等(2),ProtocolBuffer