基於socket,實現使用者註冊,使用者登入,以及檔案上傳的例子
阿新 • • 發佈:2019-02-07
觀看慕課網關於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.課程連結