序
本文主要小结一下通信协议设计的要点。
考虑点
1、采用什么传输协议
TCP还是UDP还是HTTP,即在哪一层进行传输
2、采用什么传输格式
即编码协议及序列化方式
(1)采用什么字符集编码/解码
(2)单个字符到字节的顺序(big-endian还是little-endian)(3)多个字符的分隔方式(采用分隔符还是定长方式,还是带字符长度的信息)3、消息的设计
(1)消息头
定长,包括消息版本号(1字节)、消息序列号(4字节整型)、消息数据长度(可设计为包含消息类型块的长度,或者仅仅是消息体的长度)、消息延续标志(是/否,消息超长处理用)
(2)消息类型块
请求类型:响应类型、消息体长度 回复类型:响应类型、消息体长度、错误信息(错误号、错误类型、错误内容)、消息处理标志
(3)消息体
实例
Message对象
public class XMessage { private EncodeEnum encode; private int length; private String content; public void writeUtf8(String msg){ this.encode = EncodeEnum.UTF8; this.content = msg; this.length = msg.length(); } public EncodeEnum getEncode() { return encode; } public void setEncode(EncodeEnum encode) { this.encode = encode; } public int getLength() { return length; } public void setLength(int length) { this.length = length; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "XMessage{" + "encode=" + encode + ", length=" + length + ", content='" + content + '\'' + '}'; }}
编解码
public class XProtocol { public static void encode(OutputStream outputStream,XMessage xMessage) throws IOException { //write encoding DataOutputStream dout = new DataOutputStream(outputStream); dout.writeInt(xMessage.getEncode().ordinal()); //write content length dout.writeInt(xMessage.getLength()); //write content dout.write(xMessage.getContent().getBytes(xMessage.getEncode().desc)); } public static XMessage decode(InputStream input) throws IOException { DataInputStream din = new DataInputStream(input); XMessage xMessage = new XMessage(); //get encoding int encode = din.readInt(); EncodeEnum encodeEnum = EncodeEnum.getByIdx(encode); xMessage.setEncode(encodeEnum); //get content length int length = din.readInt(); xMessage.setLength(length); //get content byte[] data = new byte[length]; din.read(data); String content = new String(data,encodeEnum.desc); xMessage.setContent(content); return xMessage; }}
Server端
public class XServer { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(9090); System.out.println("server running"); while(true){ Socket socket = server.accept(); InputStream inputStream = socket.getInputStream(); XMessage inMsg =XProtocol.decode(inputStream); System.out.println("receive from client:"+inMsg); OutputStream outputStream = socket.getOutputStream(); XMessage outMsg = new XMessage(); outMsg.writeUtf8("got our msg"); XProtocol.encode(outputStream,outMsg); socket.close(); } }}
Client端
public class XClient { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.0.1",9090); OutputStream out = socket.getOutputStream(); XMessage outMsg = new XMessage(); outMsg.writeUtf8("hello server"); XProtocol.encode(out,outMsg); InputStream inputStream = socket.getInputStream(); XMessage inMsg = XProtocol.decode(inputStream); System.out.println("receive from server:"+inMsg); }}
本工程
其他
待补充