1. 程式人生 > >基於socket,實現使用者註冊,使用者登入,以及檔案上傳的例子

基於socket,實現使用者註冊,使用者登入,以及檔案上傳的例子

觀看慕課網關於socket的視訊,完成的一個小練習,demo原始碼和課程連結會放在後面。

1.專案截圖:


2.原始碼分析

  1.server.java  伺服器端socket 需要首先啟動

package lmq.socket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
	
	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		try {
			//建立一個伺服器socket,並繫結監聽埠
			serverSocket = new ServerSocket(8888);
			System.out.println("************伺服器已啟動,等待客戶端連線*************");
			Socket socket = null;
			//記錄客戶端的數量
			int count = 0;
			//迴圈監聽客戶端的連線
			while(true){
				//呼叫accept方法進行監聽,等待客戶端連線
				socket = serverSocket.accept();
				//建立一個執行緒,處理與客戶端的互動
				SocketThread st = new SocketThread(socket);
				Thread thread = new Thread(st);
				thread.start();
				count++;
				System.out.println("當前連線的客戶端數量為:"+count);
				
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				serverSocket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

   2. SocketThread.java 執行緒處理類
package lmq.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

import lmq.entity.File;
import lmq.entity.User;
import lmq.service.FileService;
import lmq.service.UserService;
import lmq.util.CommandTransfer;

public class SocketThread implements Runnable {
	private Socket socket = null ;
	private ObjectInputStream ois = null;
	private ObjectOutputStream oos = null;
	private UserService userService = new UserService();
	private FileService fileService = new FileService();
	
	
	public SocketThread(Socket socket) {
		this.socket = socket;

	}

	@Override
	public void run() {
		try {
			InputStream is = socket.getInputStream();
			OutputStream os = socket.getOutputStream();
			ois = new ObjectInputStream(is);
			oos = new ObjectOutputStream(os);
			CommandTransfer commandTransfer = (CommandTransfer) ois.readObject();
			commandTransfer = excute(commandTransfer);//執行客戶端指令操作
			oos.writeObject(commandTransfer);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		
	}
	/**
	 * 執行客戶端指令操作
	 * @param commandTransfer
	 * @return
	 */
	private CommandTransfer excute(CommandTransfer commandTransfer) {
		String cmd = commandTransfer.getCmd();
		if(cmd.equals("register")){//使用者註冊
			User user = (User) commandTransfer.getData();
			boolean flag = userService.addUser(user);
			commandTransfer.setFlag(flag);
			if(flag){
				commandTransfer.setResult("註冊成功,請登入!");
			}else{
				commandTransfer.setResult("註冊失敗");
			}
		}
		if(cmd.equals("login")){//使用者登入
			User user = (User) commandTransfer.getData();
			boolean flag = userService.loginUser(user);
			commandTransfer.setFlag(flag);
			if(flag){
				commandTransfer.setResult("登陸成功!");
			}else{
				commandTransfer.setResult("登入失敗");
			}
		}
		if(cmd.equals("upload")){
			File file = (File) commandTransfer.getData();
			boolean flag = fileService.addFile(file);
			commandTransfer.setFlag(flag);
			if(flag){
				commandTransfer.setResult("檔案上傳成功!");
			}else{
				commandTransfer.setResult("檔案上傳失敗");
			}
		}
		return commandTransfer;
	}
}

  3. 客戶端啟動類
package lmq.socket;
/**
 * 客戶端啟動類
 * @author I
 *
 */
public class StartClient {
	public static void main(String[] args) {
		Client client = new Client();
		client.showMenu();
	}
}

4.客戶端處理類 client
package lmq.socket;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

import lmq.entity.File;
import lmq.entity.User;
import lmq.util.CommandTransfer;

public class Client {
	Socket socket = null;//客戶端socket
	Scanner sc = new Scanner(System.in);
	User user = null;
	File file = null;
	
	public  void showMenu() {
		

		
		System.out.println("**************歡迎使用lmq的檔案上傳器************");
		System.out.println("註冊使用者:1 \n使用者登入:2 \n 退出:3");
		System.out.println("*****************************************");
		System.out.print("請選擇:");
		switch (sc.nextInt()) {
		case 1:
			doRegister();
			break;
		case 2:
			doLogin();
			break;
		case 3:
			System.out.println("謝謝,再見!");
			System.exit(0);
		default:
			System.out.println("輸入有誤!");
			break;
		}
		
	}

	private void doLogin() {
		user = new User();
		CommandTransfer commandTransfer = new CommandTransfer();
		int count = 0;
		while(true){
			count++;
			//三次登入
			if(count > 3){
				System.out.println("抱歉,您已經用完三次機會,請下次登入!");
				System.exit(0);
			}
			System.out.print("請輸入使用者名稱:");
			user.setUserName(sc.next());
			System.out.print("請輸入密碼:");
			user.setUserPwd(sc.next());
			commandTransfer.setData(user);
			commandTransfer.setCmd("login");
			try {
				socket = new Socket("localhost",8888);
				sendData(commandTransfer);//向伺服器傳送資料
				commandTransfer = getData();//獲取伺服器的資料
				System.out.println(commandTransfer.getResult());
				System.out.println("**************************");
				if(commandTransfer.isFlag()){
					break;
				}
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally{
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
		}
			doUpload();
		
	}
	/**
	 * 上傳檔案
	 */
	private void doUpload() {

		CommandTransfer commandTransfer = new CommandTransfer();
		 file = new File();
		
		while(true){
			InputStream is = null;
			BufferedInputStream bis = null;
			String fname = null;
			byte[] buffer = null;
			System.out.println("請選擇需要上傳的檔案路徑:例如(d:/1.jpg)");
			String path = sc.next();
			//通過輸入流讀取本地檔案
			try {
				is = new FileInputStream(path);
				bis = new BufferedInputStream(is);
			    buffer = new byte[bis.available()];
			    //獲取檔名
			    fname = path.substring(path.lastIndexOf("/")+1);
			    bis.read(buffer);
			    //封裝file資料物件
			    file.setFname(fname);
			    file.setFcontent(buffer);
				
			} catch (FileNotFoundException e1) {
				System.out.println("檔案不存在!");
				continue;
			} catch (IOException e) {
				e.printStackTrace();
			}finally{//關閉io流
				if(null!=bis){
					
					try {
						bis.close();
					} catch (IOException e) {
						e.printStackTrace();
					}finally{
						bis = null;
					}
				}
				if(null!=is){
					
					try {
						is.close();
					} catch (IOException e) {
						e.printStackTrace();
					}finally{
						is = null;
					}
				}
				
			}
			
			
			
			try {
				socket = new Socket("localhost",8888);
				commandTransfer.setData(file);
				commandTransfer.setCmd("upload");
				sendData(commandTransfer);
				commandTransfer = getData();
				System.out.println(commandTransfer.getResult());
				if(commandTransfer.isFlag()){
					break;
				}
				
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			
		}
		
	  System.out.println("謝謝使用檔案本上傳器");
		
	}

	private  void doRegister() {
		user = new User();
		CommandTransfer commandTransfer = new CommandTransfer();
		while(true){
			System.out.print("請輸入使用者名稱:");
			user.setUserName(sc.next());
			System.out.print("請輸入密碼:");
			user.setUserPwd(sc.next());
			System.out.print("請再次確認密碼:");
			String rePassword = sc.next();
			if(!rePassword.equals(user.getUserPwd())){
				System.out.println("**********兩次輸入的密碼不一致***********");
				continue;
			}
			commandTransfer.setCmd("register");
			commandTransfer.setData(user);
			try {
				socket = new Socket("localhost", 8888);
				sendData(commandTransfer);//傳送資料給伺服器
				commandTransfer = getData();//獲取伺服器返回的資料
				System.out.println(commandTransfer.getResult());
				System.out.println("***************************");
				if(commandTransfer.isFlag()){
					break;//如果註冊成功,則不再重複註冊
				}
				
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		//註冊成功直接登入
		 doLogin();
		
	}
	/**
	 * 獲取伺服器返回的資料
	 * @return
	 */
	private CommandTransfer getData() {
		InputStream is;
		ObjectInputStream osi;
		CommandTransfer commandTransfer = null;
		try {
			is = socket.getInputStream();
			osi = new ObjectInputStream(is);
			commandTransfer= (CommandTransfer) osi.readObject();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		return commandTransfer;
	}
	/**
	 * 向伺服器傳送資料
	 * @param commandTransfer
	 */
	private void sendData(CommandTransfer commandTransfer) {
		try {
			OutputStream os = socket.getOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(os);
			oos.writeObject(commandTransfer);
			oos.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}

最關鍵的是util包下的CommandTransfer.java 用於客戶端與伺服器之間指令資料的封裝
package lmq.util;

import java.io.Serializable;
/**
 * 表示客戶機和伺服器之間傳輸的指令資料
 * @author I
 *
 */
public class CommandTransfer implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private Object data;//傳輸資料
	private String result;//返回結果
	private boolean flag;//操作是否成功
	private String cmd;//操作指令
	public CommandTransfer() {
		super();
	}
	public Object getData() {
		return data;
	}
	public void setData(Object data) {
		this.data = data;
	}
	public String getResult() {
		return result;
	}
	public void setResult(String result) {
		this.result = result;
	}
	public boolean isFlag() {
		return flag;
	}
	public void setFlag(boolean flag) {
		this.flag = flag;
	}
	public String getCmd() {
		return cmd;
	}
	public void setCmd(String cmd) {
		this.cmd = cmd;
	}
	
}


其他資料庫操作就不提了,下面是連結:

  2.課程連結