我想让客户端从文件读取数据,然后按照如下格式发送消息,请问如何实现?
字段 长度(单位字节) 内容
--------------------------------------------------------------------
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
字段 长度(单位字节) 内容
--------------------------------------------------------------------
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
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();
}}