通訊協議設計要點

本文主要小結一下通訊協議設計的要點。java

考慮點

一、採用什麼傳輸協議

TCP仍是UDP仍是HTTP,即在哪一層進行傳輸git

二、採用什麼傳輸格式

即編碼協議及序列化方式github

(1)採用什麼字符集編碼/解碼
(2)單個字符到字節的順序(big-endian仍是little-endian)
(3)多個字符的分隔方式(採用分隔符仍是定長方式,仍是帶字符長度的信息)socket

三、消息的設計

(1)消息頭ide

定長,包括消息版本號(1字節)、消息序列號(4字節整型)、消息數據長度(可設計爲包含消息類型塊的長度,或者僅僅是消息體的長度)、消息延續標誌(是/否,消息超長處理用)

(2)消息類型塊this

請求類型:響應類型、消息體長度
    回覆類型:響應類型、消息體長度、錯誤信息(錯誤號、錯誤類型、錯誤內容)、消息處理標誌

(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設計

其餘

待補充code

相關文章
相關標籤/搜索