时间:2020-10-16 12:36:55 | 栏目:JAVA代码 | 点击:次
云端共享小程序:
首先介绍一些程序功能:多用户共享资源,创建一个共享服务器,服务器存储器可以存放资源,用户可以向服务器上传文件,也可以从服务器下载文件,实现了多用户分享资源的功能。
技术栈
1.集合框架(Map集合)
2.IO流(对象序列化,文件传输等)
3.多线程
4.网络编程(TCP/IP协议)
5.简单的GUI界面
来看下界面效果(本人喜欢粉色,用户可以自定义颜色…):
点击下载后:
具体不再详述,看程序:服务端:
package com.softeem.clound.server; import java.io.File; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Map; import com.softeem.clound.ToolsAndUI.Tools; /*** * 云端共享服务器: * 实现多用户云端共享资源 * @author gq * */ public class CloudServer extends Thread { /** 套接字 */ private Socket s; /** 文件Map集合 */ Map<String, File> map = new HashMap<String, File>(); /** 服务器暂存文件的文件夹(这里我用电脑作为服务器) */ File file = new File("C:\\Users\\14252\\Desktop\\keepFiles"); /** * 定义构造器初始化套接字 * * @param s */ public CloudServer(Socket s) { this.s = s; } @Override public void run() { File files[] = file.listFiles(); // 先将服务器文件加入到结合中去 for (File file : files) { map.put(file.getName(), file); } // 先询问用户下载还是上传 try { /* * // 将选择发送给用户 String msg = "欢迎进入云端共享(先选择您的操作)"; * Tools.sendMsg(s.getOutputStream(), msg); */ // 接收到用户的回复 String s1 = Tools.getMsg(s.getInputStream()); // 得到用户请求进行操作 if (s1.equals("1")) { Tools.tips("用户选择了下载操作!"); downLoad(); } else if ("2".equals(s1)) { Tools.tips("用户选择了上传操作!"); upLoad(); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 下载文件 * * @throws IOException */ private void downLoad() throws IOException { /** * 将文件集合序列化传给用户 */ Tools.transObject(map, s.getOutputStream()); // 得到用户下载文件的名字(用户发来的名字可能有空格,去除空格) String name = Tools.getMsg(s.getInputStream()).trim(); // 通过对面传过来的文件名找到文件 File file = map.get(name); // 将文件传输给用户 Tools.transFile(s.getOutputStream(), file); // 将传输成功的信息打印到控制台 Tools.tips(file.getName() + ":传输完成"); // 通过半关闭将输出流关闭,解决服务端阻塞问题 s.shutdownOutput(); } /** * 用户上传文件 * * @throws IOException * @throws ClassNotFoundException */ private void upLoad() throws ClassNotFoundException, IOException { // 通过对象序列化得到文件对象 Object obj = Tools.getObject(s.getInputStream()); File f = (File) obj; // 设置好文件路径 file = new File(file, f.getName()); // 传输信息解决阻塞问题 Tools.sendMsg(s.getOutputStream(), ""); // 获取文件 Tools.getFile(s.getInputStream(), file); // 服务器控制台显示用户下载成功 Tools.tips(file.getName() + " 文件上传成功"); } public static void main(String[] args) throws IOException { // 设置一个端口为5555的服务器 ServerSocket server = new ServerSocket(5555); // 不断循环接收多个用户请求 while (true) { // 监听用户请求 Socket s = server.accept(); // 当监听到用户请求时,创建线程执行任务 new CloudServer(s).start(); // 将每个客户进入到服务器的信息打印到控制台 Tools.tips("客户端访问了服务器:" + s.getInetAddress().getHostAddress()); } } }
工具类:
package com.softeem.clound.ToolsAndUI; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; 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; /** * 工具类 * @author 14252 */ public class Tools { /** * * 将套接字输出流包装成打印流并且打印信息 * @param os * @param msg * @throws IOException */ public static void Println(OutputStream os, String msg) throws IOException { } public static String getMsg(InputStream in) throws IOException { InputStreamReader isr = new InputStreamReader(in); BufferedReader br = new BufferedReader(isr); String s1 = null; s1 = br.readLine(); return s1; } /** * 简化输出语句 * * @param s */ public static void tips(String s) { System.out.println(s); } /** * 传输(发送)文件 * @param os * @param file * @throws IOException */ public static void transFile(OutputStream os, File file) throws IOException { BufferedOutputStream fos = new BufferedOutputStream(os); byte b[] = new byte[1024]; FileInputStream fis = new FileInputStream(file); int len = 0; while ((len = fis.read(b)) != -1) { fos.write(b, 0, len); } fos.flush(); } /** * 发送消息 * @param os * @param msg */ public static void sendMsg(OutputStream os, String msg) { PrintWriter pw = new PrintWriter(os); pw.println(msg); pw.flush(); } /** * 接收文件 * @param in * @param file * @throws IOException */ public static void getFile(InputStream in, File file) throws IOException { BufferedInputStream bu = new BufferedInputStream(in); int len = 0; byte b[] = new byte[1024]; // System.out.println("下载完成!"); FileOutputStream fos = new FileOutputStream(file); while ((len = bu.read(b)) != -1) { fos.write(b, 0, len); } fos.flush(); } /** * 定义泛型方法传输序列化对象 * @param t * @param os * @throws IOException */ public static <T>void transObject(T t,OutputStream os) throws IOException{ ObjectOutputStream oos=new ObjectOutputStream(os); oos.writeObject(t); } /** * 定义泛型方法反序列化序列化对象 * @param in * @return * @throws ClassNotFoundException * @throws IOException */ public static Object getObject(InputStream in) throws ClassNotFoundException, IOException{ ObjectInputStream ois = new ObjectInputStream(in); Object o= ois.readObject(); return o; } }
界面
package com.softeem.clound.ToolsAndUI; import java.awt.Color; import java.awt.Container; import java.awt.Font; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTextArea; /** * JFrame界面 * * @author 14252 * */ public class MyJFrame extends JFrame { private static final long serialVersionUID = -82252562835060372L; // 确认按钮 public static JButton jb1 = new JButton("确认"); public static JButton jb2 = new JButton("确认"); public static JButton jbDown = new JButton("下载"); public static JButton jbUp = new JButton("上传"); // 文本框 public static JTextArea jt2 = new JTextArea(); public static JTextArea jt = new JTextArea(); public static JTextArea jt1 = new JTextArea(); public static JScrollPane js = new JScrollPane(); // 标签 public static JLabel j1 = new JLabel("输入您要下载的文件名"); public static JLabel j2 = new JLabel("输入上传文件路径"); /** * 显示窗口 */ public static void showJFrame() { JFrame jf = new JFrame(); /** 设置窗口 */ jf.setTitle("云端文件共享mini版"); jf.setSize(520, 700); jf.setLayout(null); jf.setVisible(true); jf.setResizable(false); // 设置容器 Container c = jf.getContentPane(); /** 设置滚动条以及文本框 */ js.setBounds(50, 50, 400, 200); c.add(js); jt.setFont(new Font("", 20, 16)); jt.setBounds(50, 50, 400, 200); js.setViewportView(jt); c.add(jt); /** 设置上传下载按钮 */ jbDown.setBounds(50, 280, 100, 40); jbUp.setBounds(350, 280, 100, 40); c.add(jbUp); c.add(jbDown); /** 设置按钮1以及文本框1以及标签1 */ jb1.setBounds(350, 350, 100, 40); c.add(jb1); j1.setBounds(50, 360, 300, 100); j1.setFont(new Font("", 20, 20)); j1.setForeground(Color.RED); c.add(j1); jt1.setBounds(50, 350, 240, 40); jt1.setFont(new Font("", 18, 18)); js.setViewportView(jt); c.add(jt1); /** 设置按钮2以及文本框2以及标签2 */ jb2.setBounds(350, 500, 100, 40); c.add(jb2); jt2.setBounds(50, 500, 240, 40); c.add(jt2); j2.setBounds(50, 510, 300, 100); j2.setFont(new Font("", 20, 20)); j2.setForeground(Color.RED); c.add(j2); jt2.setFont(new Font("", 17, 17)); /** 设置背景颜色 */ c.setBackground(Color.PINK); } }
服务端:
package com.softeem.clound.cilent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.net.Socket; import com.softeem.clound.ToolsAndUI.MyJFrame; import com.softeem.clound.ToolsAndUI.Tools; /** * 客户端 * * @author gq */ public class CilentSharing { /** 套接字 */ private Socket s; /** 下载到的路径 */ File file1; /** 定义一个状态(1 下载 2 上传) */ String ss; /** 服务器ip地址 */ private String ip; /** 服务器端口号 */ private int port; public CilentSharing(File file1, String ip, int port) { this.file1 = file1; this.ip = ip; this.port = port; } public CilentSharing() { } /** * 选择进行的操作 * * @throws IOException * @throws ClassNotFoundException */ private void choose() throws IOException, ClassNotFoundException { // 下载 downLoad(); // 上传 upLoad(); } /** * 下载功能(点击下载按钮启动) */ private void downLoad() { // 点击下载按钮开始下载 MyJFrame.jbDown.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { s = new Socket(ip, port); } catch (IOException e2) { e2.printStackTrace(); } // 将你的选择发送给服务端(1,2) try { ss = "1"; Tools.sendMsg(s.getOutputStream(), ss); // 启动下载线程 new DownlownServer(s, file1).start(); return; } catch (IOException e1) { e1.printStackTrace(); } } }); } /** * 上传文件功能(点击上传按钮启动) */ private void upLoad() { MyJFrame.jbUp.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { MyJFrame.jt.setText("请输入您要上传文件所在路径!"); s = new Socket(ip, port); // 将选择发给服务端 ss = "2"; Tools.sendMsg(s.getOutputStream(), ss); // 开启上传线程 new UpServer(s).start(); } catch (IOException e1) { e1.printStackTrace(); } } }); } /** * 开始任务 * * @throws ClassNotFoundException * @throws IOException */ public static void main(String[] args) throws ClassNotFoundException, IOException { // 启动界面 MyJFrame.showJFrame(); // 说明 MyJFrame.jt.setText("欢迎使用云端共享!!!" + "\n" + "注意:" + "\n" + "在上传文件填写路径前或选择下载文件时" + ",先选择您的" + "\n" + "操作(上传/下载)"); // 文件下载的路径(这里写自己的保存路径) File f = new File("C:\\Users\\14252\\Desktop\\新建文件夹 (4)"); // 端口号 int port = 5555; // ip地址 String ip = "192.168.0.102"; // 调用选择进行操作的方法 new CilentSharing(f, ip, port).choose(); } }
客户端下载服务线程:
package com.softeem.clound.cilent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.net.Socket; import java.util.HashMap; import java.util.Map; import com.softeem.clound.ToolsAndUI.MyJFrame; import com.softeem.clound.ToolsAndUI.Tools; /** * 创建线程回应下载点击事件 * * @author gq * */ public class DownlownServer extends Thread { /** socket套接字 */ Socket s; /** 用户的下载路径 */ File file; /** 接收传过来的map集合 */ Map<String, File> map; /** 接收文本框内容 */ String msg; /** 接受所有文件信息 */ String show=""; public DownlownServer(Socket s, File file) { this.s = s; this.file = file; } @Override public void run() { // 创建线程执行下载任务 // 反对象序列化(得到map集合) Object obj = null; try { obj = Tools.getObject(s.getInputStream()); } catch (ClassNotFoundException | IOException e2) { // TODO 自动生成的 catch 块 e2.printStackTrace(); } // 得到Map集合 map = (HashMap<String, File>) obj; // 将服务器文件信息显示到这里 map.forEach((k, v) -> { show = show + "文件名: " + k + "\n"; }); // 将可以下载的文件列出来 MyJFrame.jt.setText(show); // 按钮点击事件下载文件 MyJFrame.jb1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // 将选择的文件名字传给服务端 try { msg = MyJFrame.jt1.getText().trim(); // 将下载文件名字传给服务器 Tools.sendMsg(s.getOutputStream(), msg); // 将服务端文件下载下来 File f = new File(""); // 接收原路径 f = file; file = new File(file, msg); // 接收文件 Tools.getFile(s.getInputStream(), file); MyJFrame.j1.setText("下载成功!!!"); // 恢复原路径可以多次下载 file = f; //关闭套接字 s.close; } catch (IOException e1) { e1.printStackTrace(); } } }); } }
客户端上传线程:
package com.softeem.clound.cilent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.net.Socket; import java.util.Map; import com.softeem.clound.ToolsAndUI.MyJFrame; import com.softeem.clound.ToolsAndUI.Tools; /*** * 上传线程 * @author 14252 * */ public class UpServer extends Thread{ /***/ Socket s; File file; Map<String, File> map; String show; public UpServer(Socket s) { this.s = s; } @Override public void run() { MyJFrame.jb2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //得到输入的文件路径 String content=MyJFrame.jt2.getText(); file=new File(content); try { //将文件信息通过对象序列化传过去 Tools.transObject(file, s.getOutputStream()); //得到服务端响应避免阻塞 Tools.getMsg(s.getInputStream()); //开始传输文件 Tools.transFile(s.getOutputStream(), file); //在界面显示显示上传成功 MyJFrame.j2.setText("上传成功"); MyJFrame.jt.setText(file.getName()+"上传成功!"); // 通过半关闭将输出流关闭,解决服务端阻塞问题 s.shutdownOutput(); } catch (IOException e1) { e1.printStackTrace(); } } }); } }
总结:
这个小程序综合性比较强,所以代码量较多,可以一直下载或者上传,多线程之间互不影响,每次点击下载或者上传都会创建一个线程进行下载或上传,各个任务之间互不影响,上面程序还可以继续扩展和优化,比如加入进度显示,大厅通知所有人某个用户上传了什么,下载了什么,这里不再叙述。