慕課網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;
}
}