Socket实例之客户端向服务端数据库上传文件UI版

来源:互联网 发布:异地淘宝客服靠谱吗 编辑:程序博客网 时间:2024/06/10 23:56

运行结果:

首先实现分析:

1用户注册
客户单选择‘用户注册’,提示要输入用户名,密码,确认密码,校验成功后将用户
信息保存到数据库,并提示数据库注册成功,请登录
2用户登录
客户端选择‘登录以后’后,提示输入用户名和密码,验证成功则提示上传文件
,验证失败则给出提示信息,并可以重新登录
3文件上传
客户端输入上传文件的路径,并读取文件数据,通过输出流发送到服务端,服务端接受
后将上传文件保持在数据库

所有类如图:


cn.edu.xynu.entity包里面有两个实体类

分别是数据库中的用户内容和文件内容。

数据库中的两张表的设计如下图


User实体类。和数据库的user表内容一致

package cn.edu.xynu.entity;import java.io.Serializable;public class User implements Serializable{/** * 用户的实体类 */private static final long serialVersionUID = 4015036439904829095L;private String username;private String password;public User() {super();// TODO Auto-generated constructor stub}public User(String username, String password) {super();this.username = username;this.password = password;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}

File实体类和数据库的File表内容一致

package cn.edu.xynu.entity;import java.io.Serializable;public class File implements Serializable{/** * 文件的实体类 */private static final long serialVersionUID = 1L;private String fname;private String username;private byte[] fcontent;public File() {super();// TODO Auto-generated constructor stub}public File(String fname, String username, byte[] fcontent) {super();this.fname = fname;this.username = username;this.fcontent = fcontent;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getFname() {return fname;}public void setFname(String fname) {this.fname = fname;}public byte[] getFcontent() {return fcontent;}public void setFcontent(byte[] fcontent) {this.fcontent = fcontent;}}
cn.edu.xynu.service包里主要是对业务的实现

FileService 类实现客户端文件向服务器数据库的上传

package cn.edu.xynu.service;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import cn.edu.xynu.entity.File;import cn.edu.xynu.util.DBHelper;/** * @author scx * 文件服务类 */public class FileService {//上传文件public boolean uploadFile(File file) {Connection conn = null;PreparedStatement ps = null;conn = DBHelper.getConnection();String sql = "insert into file (username,filename,filecontent) values(?,?,?)";try {ps = conn.prepareStatement(sql);ps.setString(1, file.getUsername().trim());ps.setString(2, file.getFname().trim());ps.setBytes(3, file.getFcontent());int n=ps.executeUpdate();if(n>0){return true;}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {if(conn!=null)conn.close();if(ps!=null)ps.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return false;}}

UserService类主要实现用户的登录和注册

package cn.edu.xynu.service;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import cn.edu.xynu.entity.User;import cn.edu.xynu.util.DBHelper;/** * @author scx *用户服务类 */public class UserService {private Connection conn = null;private PreparedStatement ps = null;//检测账户在数据库是否存在public boolean checkUser(User user) {String username = user.getUsername();String password = user.getPassword();try {conn = DBHelper.getConnection();String sql = "select * from user where username =? and password=?";ps = conn.prepareStatement(sql);ps.setString(1, username);ps.setString(2, password);ResultSet rs = ps.executeQuery();rs.last();int n = rs.getRow();if (n > 0) {return true;}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {try {if (ps != null)ps.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return false;}//在数据库中添加注册的用户public boolean addUser(User user) {String username = user.getUsername();String password = user.getPassword();try {conn = DBHelper.getConnection();String sql = "insert into user (username,password) values(?,?)";ps = conn.prepareStatement(sql);ps.setString(1, username);ps.setString(2, password);int x = ps.executeUpdate();if (x > 0) {return true;}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {try {if (ps != null)ps.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return false;}}

然后cn.edu.xynu.socket包里面主要是socket编程的类

Client类实现与服务端的通信

package cn.edu.xynu.socket;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.net.Socket;import cn.edu.xynu.util.CommandTranser;/** * @author scx *客户端 */public class Client {public static Socket socket=null;public static int port=8888;public static String address="127.0.0.1";//获得服务器的数据public static CommandTranser getData() {// TODO Auto-generated method stubObjectInputStream ois=null;CommandTranser res=null;try {ois=new ObjectInputStream(Client.socket.getInputStream());res=(CommandTranser) ois.readObject();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(ois!=null){try {ois.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}return res;}//向服务器发送数据public static void sendData(CommandTranser cmd) {// TODO Auto-generated method stubObjectOutputStream oos=null;try {oos=new ObjectOutputStream(Client.socket.getOutputStream());oos.writeObject(cmd);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

Service类服务端主要实现监听客户端的连接

package cn.edu.xynu.socket;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import javax.swing.JOptionPane;/** * @author scx *服务端 */public class Service {public Service(){try {ServerSocket ss=new ServerSocket(8888);Socket socket=null;JOptionPane.showMessageDialog(null, "服务器已启动!请连接...");//循环监听客户端的连接while(true){socket=ss.accept();//为每个客户开启一个线程ServiceThread serviceThread=new ServiceThread(socket);Thread thread=new Thread(serviceThread);thread.start();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

服务器线程类,ServiceThread,多线程实现多用户的连接

package cn.edu.xynu.socket;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.net.Socket;import cn.edu.xynu.entity.File;import cn.edu.xynu.entity.User;import cn.edu.xynu.service.FileService;import cn.edu.xynu.service.UserService;import cn.edu.xynu.util.CommandTranser;/** * @author scx *服务器线程 */public class ServiceThread implements Runnable {private Socket socket;public ServiceThread(Socket socket) {this.socket = socket;}@Overridepublic void run() {// TODO Auto-generated method stubObjectInputStream ois = null;ObjectOutputStream oos = null;try {ois = new ObjectInputStream(socket.getInputStream());oos = new ObjectOutputStream(socket.getOutputStream());CommandTranser cmd=(CommandTranser) ois.readObject();//处理客户端发送来的数据cmd=execute(cmd);oos.writeObject(cmd);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {if(ois!=null)ois.close();if(oos!=null){oos.close();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}//处理客户端发送来的数据private CommandTranser execute(CommandTranser cmd) {// TODO Auto-generated method stub//客户端登录操作if("login".equals(cmd.getCmd())){UserService userService=new UserService();User user=(User) cmd.getData();cmd.setFlag(userService.checkUser(user));if(cmd.isFlag()){cmd.setResult("登录成功!!");}else{cmd.setResult("oh my god !!登录失败了。。");}}//客户端注册用户操作if("register".equals(cmd.getCmd())){UserService userService=new UserService();User user=(User) cmd.getData();cmd.setFlag(userService.addUser(user));if(cmd.isFlag()){cmd.setResult("恭喜你。注册成功,请登录!");}else{cmd.setResult("oh my god !!注册失败了..");}}//客户端上传文件操作if("uploadFile".equals(cmd.getCmd())){FileService fileService=new FileService();File file=(File) cmd.getData();cmd.setFlag(fileService.uploadFile(file));if(cmd.isFlag()){cmd.setResult("恭喜你,上传成功!");}else{cmd.setResult("很遗憾,上传失败!");}}return cmd;}}

cn.edu.xynu.ui 都是各种界面设计

客户端登录界面loginUI类

package cn.edu.xynu.ui;import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.IOException;import java.net.Socket;import java.net.UnknownHostException;import javax.swing.Box;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPasswordField;import javax.swing.JTextField;import cn.edu.xynu.entity.User;import cn.edu.xynu.socket.Client;import cn.edu.xynu.util.CommandTranser;/** * @author scx *客户端登录界面 */public class LoginUI extends JFrame implements ActionListener {private static final long serialVersionUID = -2686222552198867018L;private Box box1, box2, box3, baseBox;private JLabel username, password;private JTextField username_txt;private JPasswordField password_txt;private JButton login_btn, register_btn;public LoginUI() {setLayout(new FlowLayout());init();setTitle("客户端");setSize(200, 150);setLocationRelativeTo(null);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setResizable(false);setVisible(true);}private void init() {username = new JLabel("账户");password = new JLabel("密码");username_txt = new JTextField(10);password_txt = new JPasswordField(10);login_btn = new JButton("登录");register_btn = new JButton("注册");box1 = Box.createHorizontalBox();box2 = Box.createHorizontalBox();box3 = Box.createHorizontalBox();box1.add(username);box1.add(Box.createHorizontalStrut(8));box1.add(username_txt);box2.add(password);box2.add(Box.createHorizontalStrut(8));box2.add(password_txt);box3.add(login_btn);box3.add(Box.createHorizontalStrut(8));box3.add(register_btn);baseBox = Box.createVerticalBox();baseBox.add(box1);baseBox.add(Box.createVerticalStrut(5));baseBox.add(box2);baseBox.add(Box.createVerticalStrut(5));baseBox.add(box3);baseBox.add(Box.createVerticalStrut(5));add(baseBox);login_btn.addActionListener(this);register_btn.addActionListener(this);}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stub//如果点击了登录按钮  判断账户在服务器是否存在if(e.getSource()==login_btn){User user=new User();user.setUsername(username_txt.getText().trim());user.setPassword(new String(password_txt.getPassword()).trim());CommandTranser cmd =new CommandTranser();cmd.setData(user);cmd.setCmd("login");try {Client.socket=new Socket(Client.address, Client.port);//向服务器发送数据Client.sendData(cmd);//获得服务器发送的数据cmd =Client.getData();JOptionPane.showMessageDialog(null, cmd.getResult());//如果登录成功  关闭此窗口 开启上传窗口if(cmd.isFlag()){this.dispose();new UploadUI(user.getUsername());}} catch (UnknownHostException e1) {// TODO Auto-generated catch blockJOptionPane.showMessageDialog(null, "服务端未开启!");} catch (IOException e1) {// TODO Auto-generated catch blockJOptionPane.showMessageDialog(null, "服务端未开启!");}}//如果点击了注册按钮  打开注册界面if(e.getSource()==register_btn){new RegisterUI();}}}
客户端注册界面RegisterUI类

package cn.edu.xynu.ui;import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.IOException;import java.net.Socket;import java.net.UnknownHostException;import javax.swing.Box;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPasswordField;import javax.swing.JTextField;import cn.edu.xynu.entity.User;import cn.edu.xynu.socket.Client;import cn.edu.xynu.util.CommandTranser;/** * @author scx *客户端注册界面 */public class RegisterUI extends JFrame implements ActionListener{private static final long serialVersionUID = -717590965372186957L;private Box box1, box2, baseBox;private JLabel username, password,password2;private JTextField username_txt;private JPasswordField password_txt,password_txt2;private JButton cancel_btn, register_btn;public RegisterUI(){setLayout(new FlowLayout());init();setTitle("注册");setSize(250, 200);setLocationRelativeTo(null);setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);setVisible(true);setResizable(false);}private void init() {// TODO Auto-generated method stubusername = new JLabel("账户");password = new JLabel("密码");password2=new JLabel("再次输入密码");username_txt = new JTextField(10);password_txt = new JPasswordField(10);password_txt2=new JPasswordField(10);cancel_btn = new JButton("取消");register_btn = new JButton("注册");box1=Box.createVerticalBox();box2=Box.createVerticalBox();box1.add(username);box1.add(Box.createVerticalStrut(10));box1.add(password);box1.add(Box.createVerticalStrut(10));box1.add(password2);box1.add(Box.createVerticalStrut(10));box2.add(username_txt);box2.add(Box.createVerticalStrut(10));box2.add(password_txt);box2.add(Box.createVerticalStrut(10));box2.add(password_txt2);box2.add(Box.createVerticalStrut(10));baseBox=Box.createHorizontalBox();baseBox.add(box1);baseBox.add(Box.createHorizontalStrut(5));baseBox.add(box2);add(baseBox);add(register_btn);add(cancel_btn);cancel_btn.addActionListener(this);register_btn.addActionListener(this);}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif(e.getSource()==register_btn){String username=username_txt.getText().trim();String password1=new String(password_txt.getPassword()).trim();String password2=new String(password_txt2.getPassword()).trim();if(username==null||"".equals(username)){JOptionPane.showMessageDialog(null, "请输入用户名!!");return ;}if(password1==null||"".equals(password1)){JOptionPane.showMessageDialog(null, "请输入密码!!");return ;}if(!(password1.equals(password2))){JOptionPane.showMessageDialog(null, "两次输入的密码不一致!!");return ;}//向服务器发送注册信息User user=new User(username, password1);CommandTranser cmd=new CommandTranser();cmd.setCmd("register");cmd.setData(user);try {Client.socket=new Socket(Client.address, Client.port);//向服务器发送数据Client.sendData(cmd);//获得服务器发送的数据cmd =Client.getData();JOptionPane.showMessageDialog(null, cmd.getResult());} catch (UnknownHostException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}//初始化文本框if(e.getSource()==cancel_btn){username_txt.setText(null);password_txt.setText(null);password_txt2.setText(null);}}}
开启客户端界面

package cn.edu.xynu.ui;/** * @author scx *开启客户端 */public class StartClient {public static void main(String[] args) {new LoginUI();}} 


开启服务端界面,需要注意一点、

在线程中开启服务器 避免使用main线程 服务器一直开启
 main线程一直阻塞 无法对其它事物进行处理

package cn.edu.xynu.ui;import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import cn.edu.xynu.socket.Service;/** * 开启服务端界面 */public class StartServer extends JFrame implements ActionListener{private static final long serialVersionUID = 3254784569816648178L;private JButton startServer_btn;private JButton endServer_btn;private Service startService;public StartServer(){setLayout(new FlowLayout());startServer_btn=new JButton("开启服务");endServer_btn=new JButton("关闭服务");add(startServer_btn);add(endServer_btn);setTitle("服务端");setSize(300, 200);setLocationRelativeTo(null);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);startServer_btn.addActionListener(this);endServer_btn.addActionListener(this);}public static void main(String[] args) {// TODO Auto-generated method stubnew StartServer();}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif(e.getSource()==startServer_btn){if(startService==null){/* * 在线程中开启服务器  避免使用main线程 服务器一直开启  * main线程一直阻塞  无法对其它事物进行处理 */new startServerThread().start();}}//退出服务器if(e.getSource()==endServer_btn){startService=null;System.exit(0);}}private class startServerThread extends Thread{@Overridepublic void run() {// TODO Auto-generated method stubstartService=new Service();}}}

文件上传界面,主要控件有

一个选择文件按钮  一个确认上传按钮,一个显示文件路径的文本框

package cn.edu.xynu.ui;import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.BufferedInputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.net.Socket;import java.net.UnknownHostException;import javax.swing.JButton;import javax.swing.JFileChooser;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JTextField;import cn.edu.xynu.entity.File;import cn.edu.xynu.socket.Client;import cn.edu.xynu.util.CommandTranser;/** * @author scx *上传文件界面 */public class UploadUI extends JFrame implements ActionListener {private static final long serialVersionUID = -8830003248247613172L;private JFileChooser fileChooser;//文件选择对话框private JButton upload_btn, choose_btn;//上传按钮 和选择按钮private JTextField path_txt;//文件的绝对路径private String username;//成功登录的用户名public UploadUI(String username) {this.username = username;init();setTitle("上传文件");setSize(250, 200);setLocationRelativeTo(null);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);setResizable(false);}private void init() {// TODO Auto-generated method stubsetLayout(new FlowLayout());choose_btn = new JButton("选择");upload_btn = new JButton("上传");fileChooser = new JFileChooser();path_txt = new JTextField(20);add(path_txt);add(choose_btn);add(upload_btn);choose_btn.addActionListener(this);upload_btn.addActionListener(this);}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stub// 如果点击了选择文件if (e.getSource() == choose_btn) {//打开选择文件对话框int state = fileChooser.showSaveDialog(null);if (state == 0) {String pathChoose = fileChooser.getSelectedFile().getPath();path_txt.setText(pathChoose);}}// 如果点击了上传按钮if (e.getSource() == upload_btn) {if(path_txt.getText().trim()==null||"".equals(path_txt.getText().trim())){JOptionPane.showMessageDialog(null, "请先选择文件再上传!!");return ;}uploadFile();}}//上传文件private void uploadFile() {// TODO Auto-generated method stubFile file = null;FileInputStream fis = null;BufferedInputStream bis = null;String path = path_txt.getText().trim();String fname = path.substring(path.lastIndexOf("\\") + 1);try {fis = new FileInputStream(path);// fis.available返回文件的总大小byte[] fcontent = new byte[fis.available()];bis = new BufferedInputStream(fis);//读取文件内容bis.read(fcontent);//实例化file对象file = new File(fname, username, fcontent);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (bis != null)try {bis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//向服务器发送文件CommandTranser cmd = new CommandTranser();cmd.setData(file);cmd.setCmd("uploadFile");try {Client.socket = new Socket(Client.address,Client.port);//向服务器发送数据Client.sendData(cmd);//获得服务器反馈信息cmd = Client.getData();JOptionPane.showMessageDialog(null, cmd.getResult());} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

cn.edu.xynu.util包里面就是工具类 

CommandTranser类 主要负责客户端向服务端发送数据以及服务器向客户端返回的数据

package cn.edu.xynu.util;import java.io.Serializable;/** * @author scx *用户指令类 */public class CommandTranser implements Serializable{private static final long serialVersionUID = 1L;private String cmd;//操作指令private Object data;//发送的数据private boolean flag;//操作是否成功private String result;//返回的结果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;}}
数据库工具类

package cn.edu.xynu.util;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;/** * @author scx *数据库 */public class DBHelper {private static final String driver="com.mysql.jdbc.Driver";private static final String url="jdbc:mysql://localhost:3306/susu?useUnicode=true&charcterEncoding=UTF-8";private static final String username="root";private static final String password="";private static  Connection con=null;//静态块代码负责加载驱动static{try {Class.forName(driver);} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static Connection getConnection(){if(con==null){try {con=DriverManager.getConnection(url, username, password);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return con;}}

全部源码点击下载 附mysql-java的jar 包

7 0
原创粉丝点击