我想让客户端从文件读取数据,然后按照如下格式发送消息,请问如何实现?
    字段                  长度(单位字节)        内容
   --------------------------------------------------------------------
     len                    8                   整个消息长度,不包括这8个字节,类型为long
     file_name_length       1                   文件名长度,byte
     file_name             file_name_length     文件名,String
     data_length            8                   文件数据长度,long
     data                  data_length          文件数据, String
     mac                    8                   消息的MAC码,bytesocket

解决方案 »

  1.   

    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.nio.charset.Charset;
    public abstract class SendTools { public static class FileMessage{
    private String fileName;
    private String fileData;
    public String getFileName() {
    return fileName;
    }
    public void setFileName(String fileName) {
    this.fileName = fileName;
    }
    public String getFileData() {
    return fileData;
    }
    public void setFileData(String fileData) {
    this.fileData = fileData;
    }
    }

    public static class FileMessageEncoder{
    private final Charset charset = Charset.forName("UTF-8");
    public byte[] encode(FileMessage msg){
    byte[] fileName = msg.getFileName().getBytes(charset);
    byte[] fileData = msg.getFileData().getBytes(charset);
    byte[] message = new byte[25+fileName.length+fileData.length];
    long len = message.length-8;
    message[0]=(byte)((len&0xFF00000000000000L)>>56);
    message[1]=(byte)((len&0x00FF000000000000L)>>48); 
    message[2]=(byte)((len&0x0000FF0000000000L)>>40);  
    message[3]=(byte)((len&0x000000FF00000000L)>>32); 
    message[4]=(byte)((len&0x00000000FF000000L)>>24);
    message[5]=(byte)((len&0x0000000000FF0000L)>>16);  
    message[6]=(byte)((len&0x000000000000FF00L)>>8 );  
    message[7]=(byte)((len&0x00000000000000FFL)>>0 );  
    message[8]=(byte)(fileName.length&0x00FF);
    System.arraycopy(fileName, 0, message, 9, fileName.length);
    int pos = 9+fileName.length;
    len = fileData.length;
    message[pos+0]=(byte)((len&0xFF00000000000000L)>>56);
    message[pos+1]=(byte)((len&0x00FF000000000000L)>>48); 
    message[pos+2]=(byte)((len&0x0000FF0000000000L)>>40);  
    message[pos+3]=(byte)((len&0x000000FF00000000L)>>32); 
    message[pos+4]=(byte)((len&0x00000000FF000000L)>>24);
    message[pos+5]=(byte)((len&0x0000000000FF0000L)>>16);  
    message[pos+6]=(byte)((len&0x000000000000FF00L)>>8 );  
    message[pos+7]=(byte)((len&0x00000000000000FFL)>>0 );
    System.arraycopy(fileData, 0, message, pos+8, fileData.length);
    setMAC(message,fileName,fileData,pos+8+fileData.length);
    return message;
    }
    private void setMAC(byte[] message, byte[] fileName, byte[] fileData,int pos) {
    // TODO 将MAC码 填入消息数据中,起始位置是pos的位置。
    }
    }
    public static void send(FileMessage msg,OutputStream out) throws IOException{
    FileMessageEncoder encoder = new FileMessageEncoder();
    byte[] message = encoder.encode(msg);
    out.write(message);
    out.flush();
    }

    /**
     * 测试用例
     */
    public static void main(String[] args) throws IOException {
    FileMessage msg = new FileMessage();
    msg.setFileName("测试文件名.txt");
    msg.setFileData("测试文件数据。");
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    send(msg, out);
    final char [] HEXs = new char[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    byte[] message = out.toByteArray();
    for(int i=0;i<message.length;i++){
    System.out.print(HEXs[(message[i]&0xF0)>>4]);
    System.out.print(HEXs[message[i]&0x0F]);
    }
    System.out.println();
    }}