字节流协议传输文件

无论用户从界面输入的是文本还是文件,在对端的输入流读取时,依然是一个一个字节读取,所以可以通过约定字节流的传输协议实现文件的传输。

 

每种消息都由消息头和消息体组成。

消息头包括:

1、  消息总长totalLen:指这条消息一共有多少字节,用一个Int(四个字节)来表示

2、  消息类型:用一个byte来定义,2代表传输文件消息。

对于文件传输来说,消息体包括:

3、  文件名的长度len:文件名的字节数,用一个byte来表示

4、  文件名:用一个byte数组表示。

5、  文件中的数据:用一个byte数组来表示,长度为totalLen-4-1-1-len

服务器端按照以上协议模式依次从输入流中读取消息头和消息体,再输出还原为原本的文件:

private void processChat(java.net.Socket client){
		try{
		java.io.OutputStream ous = client.getOutputStream();
		java.io.InputStream ins = client.getInputStream();
		
		java.io.DataInputStream dins = new java.io.DataInputStream(ins);
		
		while(true){
			int totalLen = dins.readInt();//总长度
			byte type = dins.readByte();//类型
			
			if(type==2){//文 件类型
				byte len = dins.readByte();//文件名长度
				byte[] fn = new byte[len];
				dins.read(fn);//读取文件名
				byte[]  data = new byte[totalLen -1-4-1-fn.length];//文件数据
				dins.readFully(data);
				dins.close();//文件读取完要关闭
				
				java.io.FileOutputStream fous = new java.io.FileOutputStream("D:\\1.txt");
				fous.write(data);
				fous.flush();
				fous.close();
				
			}
		}
		}catch(Exception ef){
			ef.printStackTrace();
		}
		
	}

 

客户端:首先根据文件构造一个输出流对象,按照协议依次写出消息头和消息体的数据,实现如下:

 

 

 

/**
	 * 发送一个文件数据包
	 * @param fileName:文件的绝对路径
	 */
	private void sendFileMsg(String fileName){
		try{
			//根据文件的绝对路径创建文件对象
			File file = new File(fileName);
			//根据文件对象,构造一个输入流
			FileInputStream fins = new FileInputStream(file);
			
			int fileDataLen = fins.available(); //数据的总长度
			
			byte type = 2; //文件的类型为2,即传文件
			
			//得到文件名
			String f_name=file.getName();
			
			byte f_len=(byte) file.getName().length();
			int totalLen = 4+1+1+f_len+fileDataLen;//数据的总长度
			
			byte[] data=new byte[f_len];
			data=f_name.getBytes();
			
			dous.writeInt(totalLen); //1.写入数据的总长度
			System.out.println("数据总长度为:"+totalLen);
			dous.writeByte(type);//2.写入文件类型
			System.out.println("数据类型为:"+type);
			dous.writeByte(f_len); //3.写入文件名的长度
			System.out.println("文件名的长度为:"+f_len);
			dous.write(data);    //4.写入文件名的数据
			System.out.println("文件名为:"+f_name);
			
			byte[] fileData=new byte[fileDataLen];
			fins.read(fileData);//读入文件数据写入fileData数组中去
			dous.write(fileData);//写出到服务器的流中
			dous.flush(); //刷新流
		}catch(Exception e){
			e.printStackTrace();
		}
	}

 这样就能实现文件从客户端到服务端的传送了!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值