序
本文主要小结一下通信协议设计的要点。
考虑点
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);
}
}
本工程github
其他
待补充
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。