慕課網Socket最後項目---上傳文件到服務器

慕課網Socket最後的一個小項目,實現登錄註冊、文件上傳。

代碼中用到了Socket,Mysql,JDBC, I/O等技術。比較難的算是I/O中的序列化與反序列化,有興趣的自己可以去找找資料。

參考視頻中給出的部分代碼,加上自己的一些聯想所寫出的,可能會出一些錯誤(目前自己運行並未出現,除了上傳的文件過於大可能報錯之外)。

先放一下包類目錄


放幾個比較複雜的類:

public class FileServer {
	private Connection connection=null;
	private PreparedStatement preparedStatement=null;
	private ResultSet resultSet=null;
	
	//將文件上傳到服務器
	public boolean save(File file){
		String sql="insert into tb_file (fname,fcontent) values(?,?)";//上傳語句
		String sql2="select * from tb_file where fname=?";//搜索一下上傳的文件名,判斷是否上傳成功
		connection=DButil.getConnection();
		try {
			preparedStatement=(PreparedStatement) connection.prepareStatement(sql);
			preparedStatement.setString(1, file.getFname());
			preparedStatement.setBytes(2,file.getFcontent());
			preparedStatement.execute();
			preparedStatement=(PreparedStatement) connection.prepareStatement(sql2);
			preparedStatement.setString(1, file.getFname());
			resultSet=preparedStatement.executeQuery();
			if (resultSet.next()){//上傳成功
				return true;
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;//上傳失敗
	}
}
public class UserServer {
	private Connection connection=null;
	private PreparedStatement preparedStatement=null;
	private ResultSet resultSet=null;
	
	//用戶登錄判斷
	public boolean login(User user){
		String sql="select * from tb_user where uname=? and upassword=?";
		connection=DButil.getConnection();
		try {
			preparedStatement=(PreparedStatement) connection.prepareStatement(sql);
			preparedStatement.setString(1, user.getUname());
			preparedStatement.setString(2, user.getUpassword());
			preparedStatement.execute();
			resultSet=preparedStatement.executeQuery();//若用戶名密碼正確,resultSet爲真
			if (resultSet.next()){//登陸成功
				return true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}	
		return false;//登錄失敗
	}
	//判斷此用戶名是否存在
	public boolean doRegister(User user){
		String sql="select *from tb_user where uname=?";
		connection=DButil.getConnection();
		try {
			preparedStatement=(PreparedStatement) connection.prepareStatement(sql);
			preparedStatement.setString(1, user.getUname());
			preparedStatement.execute();
			resultSet=preparedStatement.executeQuery();
			if (resultSet.next()){
				return true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}
	//用戶註冊
	public boolean register(User user){
		
		if (doRegister(user)){
			return false;
		}else{
			String sql="insert into tb_user(uname,upassword) values (?,?)";
			connection=DButil.getConnection();
			try {
				preparedStatement=(PreparedStatement) connection.prepareStatement(sql);
				preparedStatement.setString(1, user.getUname());
				preparedStatement.setString(2, user.getUpassword());
				preparedStatement.execute();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			return true;
		}
	}
}
public class ServerThread extends Thread {
	private Socket socket=null;
	private ObjectOutputStream objectOutputStream=null;//對象輸入流
	private ObjectInputStream objectInputStream=null;//對象輸出流
	private UserServer myuser=new UserServer();//用戶業務對象
	private FileServer myfile=new FileServer();//文件業務對象
	
	//初始化socket
	public ServerThread(Socket socket) {
		this.socket=socket;
	}
	
	public void run(){
		try {
			objectInputStream=new ObjectInputStream(socket.getInputStream());
			objectOutputStream=new ObjectOutputStream(socket.getOutputStream());
			CommandTransfer commandTransfer=(CommandTransfer) objectInputStream.readObject();
			commandTransfer=execute(commandTransfer);//執行客戶端操作指令
			objectOutputStream.writeObject(commandTransfer);//響應客戶端
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
		}
		
	}
	/*
	 * 執行客戶端發送到服務端的指令
	 */

	private CommandTransfer execute(CommandTransfer commandTransfer) {
		String cmd=commandTransfer.getCmd();//獲得操作命令
		if (cmd.equals("login")){//用戶登錄
			User user=(User) commandTransfer.getData();//獲得操作命令中數據
			boolean flag=myuser.login(user);//登錄成功flag爲true
			commandTransfer.setFlag(flag);//設置命令的flag值
			if (flag){
				commandTransfer.setResult("登錄成功!");
			}else{
				commandTransfer.setResult("用戶名或密碼不正確!");
			}
		}else if(cmd.equals("register")){//用戶註冊
			User user=(User)commandTransfer.getData();
			boolean flag=myuser.register(user);
			commandTransfer.setFlag(flag);
			if (flag){
				commandTransfer.setResult("註冊成功,請登錄");
			}else{
				commandTransfer.setResult("註冊失敗,此用戶名已存在!");
			}
		}else{//文件上傳
			File file=(File) commandTransfer.getData();
			boolean flag=myfile.save(file);
			commandTransfer.setFlag(flag);
			if (flag){
				commandTransfer.setResult("上傳成功!");
			}else{
				commandTransfer.setResult("上傳失敗!");
			}
		}
		return commandTransfer;
	}

}
public class StartServer {
	private static ServerSocket serverSocket=null;

	public static void main(String[] args) {
		try {
			//創建一個服務器socket,並綁定監聽端口
			serverSocket = new ServerSocket(8888);
			Socket socket=null;
			System.out.println("****服務端已經啓動****");
			//循環監聽客戶端的鏈接
			while (true){
				//調用accept方法監聽
				socket=serverSocket.accept();
				ServerThread serverThread=new ServerThread(socket);
				serverThread.start();
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
public class SocketClient {
	private Scanner in=new Scanner(System.in);
	private Socket socket=null;
	//主菜單
	public void showMenu(){
		System.out.println("*****歡迎使用文件上傳器*****");
		System.out.println("1、登錄\n2、註冊\n3、退出");
		System.out.println("**********************");
		System.out.println("請選擇:");
		int choice=in.nextInt();
		switch (choice) {
		case 1:
			clientLogin();
			break;
		case 2:
			clientRegister();
			break;
		case 3:
			System.out.println("再見,感謝您對本系統的支持!");
			System.exit(0);
			break;
		default:
			System.out.println("輸入有誤!");
			System.exit(0);
		}
	}
	
	//用戶登錄
	private void clientLogin() {
		User user=new User();//創建用戶實例
		CommandTransfer commandTransfer=new CommandTransfer();//創建命令實例
		int count=0;
		while (true){
			count++;
			if (count>3){
				System.out.println("你已經連續三次登錄失敗,系統退出!");
				System.exit(0);
			}
			in.nextLine();//吃掉回車,否則用戶名輸入跟密碼輸入會一塊顯示
			System.out.print("請輸入用戶名:");
			String name=in.nextLine();
			user.setUname(name);
			System.out.print("請輸入密碼:");
			String password=in.nextLine();
			user.setUpassword(password);
			commandTransfer.setCmd("login");//設置命令的cmd值
			commandTransfer.setData(user);//設置命令的data值
			
			try {
				socket=new Socket("127.0.0.1", 8888);
				sendData(commandTransfer);//將數據發送到服務器
				commandTransfer=getDate();//獲取服務器返回的數據
				System.out.println(commandTransfer.getResult());//輸出顯示結果
				System.out.println("***************************");
				if(commandTransfer.isFlag()){
					break;//如果登錄成功則不再重複登錄
				}else{
					System.out.println("請重新登錄!");
				}
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				closeAll();//結束本次socket通信
			}
		}
		clientUploadFile();
	}
	//用戶註冊
	private void clientRegister() {
		in.nextLine();//同上,吃回車
		User user=new User();
		CommandTransfer commandTransfer=new CommandTransfer();
		while (true) {
			System.out.println("請輸入用戶名:");
			String name=in.nextLine();
			user.setUname(name);
			System.out.println("請輸入密碼:");
			String password=in.nextLine();
			System.out.println("請再次輸入密碼:");
			String repassword=in.nextLine();
			if (!password.equals(repassword)){
				System.out.println("兩次密碼不一樣!");
				continue;
			}
			user.setUpassword(password);
			commandTransfer.setCmd("register");
			commandTransfer.setData(user);
			
			try {
				socket=new Socket("127.0.0.1", 8888);
				sendData(commandTransfer);//將數據發送到服務器
				commandTransfer=getDate();//獲取服務器返回的數據
				System.out.println(commandTransfer.getResult());//輸出顯示結果
				if (commandTransfer.isFlag()){
					clientLogin();//註冊成功,跳到登錄界面
				}else{
					System.out.println("請重新註冊!");
					clientRegister();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				closeAll();//結束本次通信
			}
		}
	}
	//文件上傳
	public void clientUploadFile(){
		System.out.println("請輸入上傳文件的絕對路徑(如e:\\imooc\\dog.jpg)");
		String path=in.nextLine();
		File file=null;
		FileInputStream fileInputStream=null;
		BufferedInputStream bufferedInputStream=null;
		String fname=path.substring(path.lastIndexOf("\\")+1);
		
		try {
			fileInputStream=new FileInputStream(path);
			byte []fcontent=new byte[fileInputStream.available()];
			bufferedInputStream=new BufferedInputStream(fileInputStream);
			bufferedInputStream.read(fcontent);
			file=new File(fname, fcontent);//初始化file實例
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				bufferedInputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		CommandTransfer commandTransfer=new CommandTransfer();
		commandTransfer.setCmd("uploadFile");
		commandTransfer.setData(file);
		try {
			socket=new Socket("127.0.0.1", 8888);
			sendData(commandTransfer);
			commandTransfer=getDate();
			System.out.println(commandTransfer.getResult());
			if (commandTransfer.isFlag()){
				showMenu();
			}else{
				System.out.println("請重新上傳:");
				clientUploadFile();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			closeAll();
		}
		
	}
	//關閉socket
	private void closeAll() {
		try {
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	//獲取指令中數據
	private CommandTransfer getDate() {
		CommandTransfer commandTransfer=null;
		try {
			InputStream inputStream=socket.getInputStream();
			ObjectInputStream objectInputStream=new ObjectInputStream(inputStream);
			commandTransfer=(CommandTransfer) objectInputStream.readObject();
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
		}
		return commandTransfer;
	}

	//發送數據
	private void sendData(CommandTransfer commandTransfer) {
		try {
			OutputStream outputStream=socket.getOutputStream();
			ObjectOutputStream objectOutputStream=new ObjectOutputStream(outputStream);
			objectOutputStream.writeObject(commandTransfer);
			objectOutputStream.flush();
		
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
public class CommandTransfer implements Serializable {
	private static final long serialVersionUID = -1268912978480007796L;
	
	private String cmd;//操作指令
	private Object data;//傳輸數據
	private boolean flag;//操作是否成功
	private String result;//返回結果
	
	//創建get/set方法
	public String getCmd() {
		return cmd;
	}
	public void setCmd(String cmd) {
		this.cmd = cmd;
	}
	public Object getData() {
		return data;
	}
	public void setData(Object data) {
		this.data = data;
	}
	public boolean isFlag() {
		return flag;
	}
	public void setFlag(boolean flag) {
		this.flag = flag;
	}
	public String getResult() {
		return result;
	}
	public void setResult(String result) {
		this.result = result;
	}
	
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章