Java Socket 多线程实现文件传输

        高级操作系统作业,让用Socket实现文件传输,有些代码也是在网上找的,写的不好,如果大家能用就用上。

客户端类:

 

package edu.logic.client;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

import edu.logic.common.Transmission;
import edu.logic.constant.Constant;

/**
 * 客户端类
 * @author Logic Luo
 */
public class Client {
	
	//用于从文件中读取要上传的数据
	DataInputStream dataInputStreamUploade = null;
	//用于向socket中写入数据
	DataOutputStream dataOutputStreamUploade = null;
	//用于接收从socket传来的数据
	DataInputStream dataInputStreamReceive = null;
	//用于向客户端文件中写数据
	DataOutputStream dataOutputStreamReceive = null;
	
	/**
	 * 客户端开始程序
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	@SuppressWarnings("resource")
	public void start() throws UnknownHostException, IOException {
		while(true) {
			System.out.println("请按照以下格式书写命令:\n上传文件:put 本地文件名 服务器文件名\n下载文件:get 服务器文件名 本地文件名");
			String localFileName = null;
			String remoteFileName = null;
			Scanner scanner = new Scanner(System.in);
			String command = scanner.nextLine();
			//命令解析
			String[] commandArray = command.split(" ");
			Socket socket = null;
			int flag = 0;
			
			//命令解析
			if(commandArray[0].equals("put")) {
				flag = 0;
				localFileName = commandArray[1];
				remoteFileName = commandArray[2];
			} else {
				flag = 1;
				localFileName = commandArray[2];
				remoteFileName = commandArray[1];
			}
			
			//创建socket,向服务器端发送链接请求 
			socket = new Socket(Constant.HOSTIP, Constant.PORT);
			
			dataOutputStreamUploade = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
			//向服务器端发送上传或下载标志
			dataOutputStreamUploade.writeInt(flag);
			dataOutputStreamUploade.flush();
			//想服务器端发送远程文件名
			dataOutputStreamUploade.writeUTF(remoteFileName);
			dataOutputStreamUploade.flush();
			if(flag == 0) {
			//向服务器端发送文件名称
			put(localFileName, dataOutputStreamUploade);
			dataOutputStreamUploade.close();
System.out.println("客户端上传数据完成");
			} else {
				dataInputStreamReceive = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
				get(localFileName, dataInputStreamReceive);
System.out.println("客户端数据接收完成");
				dataInputStreamReceive.close();
			}
			dataOutputStreamUploade.close();
			socket.close();
			System.out.println("File transfer complete");
		}
	}
	
	/**
	 * 从客户端向服务器上传数据
	 * @param fileName 客户端文件名
	 * @param dataOutputStreamUploade
	 * @throws IOException
	 */
	public void put(String fileName, DataOutputStream dataOutputStreamUploade) throws IOException {
		File file = new File(Constant.CLIENTFOLDER + fileName);
		//创建文件输入流
		dataInputStreamUploade = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
		Transmission transmission = new Transmission(dataInputStreamUploade, dataOutputStreamUploade);
		transmission.transmitData();
		dataInputStreamUploade.close();
	}
	
	/**
	 * 从服务器向客户端下载数据
	 * @param fileName 客户端文件名
	 * @param dataInputStreamReceive socket接收数据的输入流
	 * @throws IOException
	 */
	public void get(String fileName, DataInputStream dataInputStreamReceive) throws IOException {
		//创建文件输出流
		dataOutputStreamReceive = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(new File(Constant.CLIENTFOLDER + fileName))));
		Transmission transmission = new Transmission(dataInputStreamReceive, dataOutputStreamReceive);
		transmission.transmitData();
		dataOutputStreamReceive.close();
		dataInputStreamReceive.close();
	}
	
	public static void main(String[] args) throws Exception {
		new Client().start();
	}
}

 服务器类:

 

 

package edu.logic.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import edu.logic.constant.Constant;
/**
 * Server类
 * @author Logic Luo
 */
public class Server extends Thread{
	private Socket socket = null;
	private ServerSocket serverSocket = null;
	public static int count = 0;
	
	/**
	 * 无参构造函数
	 */
	public Server(){
		try {
			serverSocket = new ServerSocket(Constant.PORT);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public void run() {
		while(true) {
			System.out.println("进行socket监听!");
			try {
				//获监听过来的socket
				socket = serverSocket.accept();
				System.out.println(count++);
				new ServerThread(socket).start();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 主函数 
	 * @param args
	 */
	public static void main(String[] args) {
		new Server().start();
	}

}

 服务器端多线程实现数据传输:

 

 

package edu.logic.server;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;

import edu.logic.common.Transmission;
import edu.logic.constant.Constant;

/**
 * 处理文件的上传和下载
 * @author Logic Luo
 */
public class ServerThread extends Thread {
	private Socket socket = null;
	// 用于接受送客户端传来的文件
	private DataInputStream dataInputStreamReceive = null;

	// 用于向服务器写文件
	private DataOutputStream dataOutputStreamReceive = null;
	
	//用于向客户端发送文件时读取服务器文件的内容
	private DataInputStream dataInputStreamUpload = null;
	
	//用于向客户端发送文件时,向socket写入文件
	private DataOutputStream dataOutputStreamUpload = null; 
	/**
	 * 默认无参构造函数
	 */
	public ServerThread() {}

	/**
	 * 以socket为参数的构造函数
	 * @param socket
	 */
	public ServerThread(Socket socket) {
		this.socket = socket;
	}

	
	/**
	 * 服务器端开始程序
	 * @throws IOException
	 */
	@Override
	public void run() {
		// 创建服务器端ServerSocket
		try {
			dataInputStreamReceive = new DataInputStream(new BufferedInputStream(
					socket.getInputStream()));
			
			//接收从服务器端传来的标志位是上传还是下载
			int flag = dataInputStreamReceive.readInt();
			//读取传过来的文件名
			String fileName = dataInputStreamReceive.readUTF();
			
			if(0 == flag) {
				receive(fileName, dataInputStreamReceive);
	System.out.println("服务器端接收数据完成");
				dataInputStreamReceive.close();
			} else {
				dataOutputStreamUpload = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
				upload(fileName, dataOutputStreamUpload);
				dataInputStreamUpload.close();
	System.out.println("服务器端上传数据完成");
				dataInputStreamReceive.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//关闭socket
			if(socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 接收从客户端传过来的文件
	 * @param fileName 服务器端文件名称
	 * @param dataInputStreamReceive 从socket接收数据的输入流
	 * @throws IOException
	 */
	public void receive(String fileName, DataInputStream dataInputStreamReceive) throws IOException {
		String filePath = Constant.SERVERFOLDER + fileName;
		dataOutputStreamReceive = new DataOutputStream(new BufferedOutputStream(
				new FileOutputStream(new File(filePath))));
		Transmission transmission = new Transmission(dataInputStreamReceive,
				dataOutputStreamReceive);
		transmission.transmitData();
		dataOutputStreamReceive.close();
		System.out.println("文件上传成功");
	}
	
	/**
	 * 从服务器端向客户端发送文件
	 * @param fileName 本地文件名
	 * @param dataOutputStreamUpload 向socket发送数据的输出流
	 * @throws IOException
	 */
	public void upload(String fileName, DataOutputStream dataOutputStreamUpload) throws IOException {
		dataInputStreamUpload = new DataInputStream(new BufferedInputStream(new FileInputStream(new File(Constant.SERVERFOLDER + fileName))));
		Transmission transmission = new Transmission(dataInputStreamUpload, dataOutputStreamUpload);
		transmission.transmitData();
		dataInputStreamUpload.close();
	}
	
}

 文件传输:

 

 

package edu.logic.common;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

/**
 * 用于文件传输
 * @author Logic Luo
 */
public class Transmission {
	private DataInputStream sourceStream = null;
	private DataOutputStream destinationStream = null;

	public Transmission(){}
	
	/**
	 * 根据数据流的构造函数
	 * @param sourceStream
	 * @param destinationStream
	 */
	public Transmission(DataInputStream sourceStream,
			DataOutputStream destinationStream) {
		this.sourceStream = sourceStream;
		this.destinationStream = destinationStream;
	}

	/**
	 * 数据传输
	 * @throws IOException
	 */
	public void transmitData() throws IOException {
		int bufferSize = 8192;
		byte[] buffer = new byte[bufferSize]; 
		while(true) {
			int readSize = 0;
			if(sourceStream != null ) {
				readSize = sourceStream.read(buffer);
			}
			if(readSize == -1) {
				break;
			}
			destinationStream.write(buffer, 0, readSize);
		}
		destinationStream.flush();
	}
}

 

 

用到的一些常量类

 

package edu.logic.constant;

/**
 * 程序中所用到的一些常量
 * @author Logic Luo
 */
public class Constant {
	//服务器IP
	public static String HOSTIP = "127.0.0.1";
	
	//服务器端口号
	public static int PORT = 8081;
	
	//客户端文件目录
	public static String CLIENTFOLDER = "C:/Users/Logic/workspace/FileTransmit02/src/clientfolder/";
	
	//服务器端文件目录
	public static String SERVERFOLDER = "C:/Users/Logic/workspace/FileTransmit02/src/serverfolder/";
}

 

 

整个项目在附件中,需要的可以下载一下,运行的时候记得修改一下Constant类中的CLIENTFOLDER和SERVERFOLDER两个变量。

你可能感兴趣的:(java,socket)