基于TCP协议的文件传输,传输带文件名等信息的文件流
在做tcp传输文件实验时,我一直很纠结一个问题,就是Socket客户端发送一个文件SocketServer服务端时,SocketServer只能从socket.getInputStream()中得到一个文件流,怎么才能知道这个文件流具体是什么东西,什么文件,大小多少K等信息呢?思来想去今天有了答案,就是在客户端发送文件时,把文件信息和文件合并后在写入socket输出流。
看上面图,因为SequenceInputStream的参数接收的是InputStream,那怎么把字符串文件信息变成一个读取流呢?假设我的文件信息就是文件名
byte[] info = new byte[512]; 我们规定合并流的前512字节用来保存文件新,这样在服务端就可以先读取前512字节的数据,
byte[] b = filenName.getBytes(); 把文件信息转成字节数组
for(int i=0; i<b.length; i++){ 循环把文件信息的字节填充到预先定义好的用于保存文件信息的字节数组
info[i] = b[i];
}
ByteArrayInputStream bais = new ByteArrayInputStream(info); 用这个流对象对info字节数组进行读取
SequenceInputStream sis = new SequenceInputStream(bais,文件读取流); 合并读取流
这样合并流就完成了,接着把这个合并流写入socket输出流就行了。
完整的代码:
FileCilent客户端
import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.SequenceInputStream; import java.net.Socket; public class FileClient { /** * @param args */ public static void main(String[] args) { try { Socket s = new Socket("192.168.1.100",8800); File file = new File("h:/DPP3.9_60D(1).rar"); FileInputStream fs = new FileInputStream(file); //定义一个256字节的区域来保存文件信息。 byte[] b = file.getName().getBytes(); byte[] info = Arrays.CopyOf(b,256); ByteArrayInputStream bais = new ByteArrayInputStream(info); //合并流 SequenceInputStream sis = new SequenceInputStream(bais,fs); BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream()); byte[] buf = new byte[1024]; int len = 0; while((len = sis.read(buf))!=-1){ bos.write(buf,0,len); } bos.close(); sis.close(); fs.close(); bais.close(); } catch (Exception e) { e.printStackTrace(); } } }
FileServer服务端
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class FileServer { /** * @param args */ public static void main(String[] args) { ExecutorService threadpool = Executors.newFixedThreadPool(10); try { ServerSocket ss = new ServerSocket(8800); while (true) { threadpool.execute(new UploadThread(ss.accept())); } } catch (IOException e) { e.printStackTrace(); } } } class UploadThread implements Runnable { private Socket s; UploadThread(Socket s) { this.s = s; } @Override public void run() { System.out.println(s.getInetAddress().getHostAddress()); try { BufferedInputStream bis = new BufferedInputStream(s.getInputStream()); byte[] info = new byte[256]; bis.read(info); String file_name = new String(info).trim(); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("f:/"+file_name)); byte[] buf = new byte[1024]; int len = 0; while ((len = bis.read(buf)) != -1) { bos.write(buf, 0, len); } bos.close(); bis.close(); s.close(); System.out.println(file_name+" 文件传输成功"); } catch (IOException e) { e.printStackTrace(); } } }