LengthFramer

589 阅读1分钟
package com.xf.java_tcp_ip_socket.chap3.frame;

import java.io.*;

/**
 * 发送者首先给出指定消息的长度
 */
public class LengthFramer implements Framer {
    public static final int MAXMESSAGELENGTH = 65535;
    public static final int BYTEMASK = 0xff;
    public static final int SHORTMASK = 0xffff;
    public static final int BYTESHIFT = 8;
    private DataInputStream in;
    public LengthFramer(InputStream in) throws IOException{
        this.in = new DataInputStream(in);
    }
    @Override
    public void frameMsg(byte[] message, OutputStream out) throws IOException {
        if(message.length > MAXMESSAGELENGTH){
            throw new IOException("msg too long");
        }
        //write length prefix 添加长度信息
        out.write((message.length >> BYTESHIFT) & BYTEMASK);
        out.write(message.length & BYTEMASK);
        //write message
        out.write(message);
        out.flush();
    }

    /**
     * 从输入流中提取下一帧
     * @return
     * @throws IOException
     */
    @Override
    public byte[] nextMsg() throws IOException {
        int length;
        try{
            //读取两个字节,并将它们作为大端整数进行解释
            length = in.readUnsignedShort(); //read 2 bytes
        }catch (EOFException e){
            return null;
        }
        //0 <= length <= 65535
        byte[] msg = new byte[length];
        //读取指定数量的字节。该方法将阻塞等待,直到接收到足够的字节来填满指定数组
        in.readFully(msg); // if exception, it's a framing error
        return msg;
    }
}