java socket 打包和解包自定义包头格式的数据包。
1、背景:用java接收 C++服务推过来的数据,采用TCP协议,数据格式是自定义二进制的包头+pb数据构成的数据包。
2、包头格式,二进制格式12字节长度:
{
uint32 packetlength;//包体长度
uint32 packetno;//包序号
uint16 type;//包类型
uint16 version;//版本号当前固定为100
}
3、代码实现接收和发送数据:
public class NetWork {
private Socket socket = null;
private String strHost;
private int iPort;
private DataInputStream dis = null; //用于接收数据
private DataOutputStream dos = null;//用于发送数据
public void Connect(String strHost, int iPort) {
this.strHost = strHost;
this.iPort = iPort;
try {
//创建一个Socket,跟服务器的端口链接
this.socket = new Socket();
this.socket.connect(new InetSocketAddress(this.strHost, this.iPort), 3000);
// 初始化输入输出流
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void Send(short sMsgId, byte[] byteBody) {
try {
if (socket != null && socket.isBound() && !socket.isClosed() && socket.isConnected() &&!socket.isInputShutdown() && !socket.isOutputShutdown()) {
//打包头
dos.writeInt(byteBody.length);
dos.writeInt(1);
dos.writeShort(sMsgId);
dos.writeShort(100);
//包体数据
dos.write(byteBody);
dos.flush();
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//接收数据
public String Receive() {
try {
if (socket.isClosed()) {
System.out.println("socket 关闭");
return "socket is closed";
}
//解析包头
int body_len = dis.readInt();
int packetno = dis.readInt();
int iMsgtype = dis.readUnsignedShort();
int version = dis.readUnsignedShort();
//获取数据包 pb格式
byte[] bodybuf = new byte[body_len];
if (body_len > 0) {
dis.read(bodybuf);
}
//得到byte[]就根据自己的需要转换数据类型就好了。
if (bodybuf != null && bodybuf.length > 0) {
//根据pb文件转string()
String strTemp = "根据pb文件转string";
return strTemp;
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
// 关闭流和连接
this.DisConnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
public void DisConnect() {
try {
// 关闭流和连接
dos.flush();
dos.close();
dis.close();
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4、说明:因为主语言不是java,java用的也不熟悉,不保证没问题。毕竟程序和程序员有一个能跑就行,哈哈哈哈。