Socket如何按照一定格式发送消息?

付草宝 2013-03-05 02:01:55
我想让客户端从文件读取数据,然后按照如下格式发送消息,请问如何实现?
字段 长度(单位字节) 内容
--------------------------------------------------------------------
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码,byte
...全文
138 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
小绵羊 2013-03-05
  • 打赏
  • 举报
回复
用DataInputStream和DataOutputStream
冰思雨 2013-03-05
  • 打赏
  • 举报
回复
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();
	}

}

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧