java网络编程:DatagramSocket类简单实现文件下载
来源:互联网 发布:js 跳转url 编辑:程序博客网 时间:2024/05/29 01:56
1、服务器端代码
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 下载服务器,采用UDP协议,传送的过程中可能会丢包,导致下载的文件不完整 */ public class DownloadServer { // 提供服务 public void service() { try { // 创建本机指定端口8289的服务器 DatagramSocket dataSocket = new DatagramSocket(8289); // 线程池,固定有十个线程 ExecutorService ThreadPool = Executors.newFixedThreadPool(10); while (true) {// 不断接收来自客户端的请求 byte[] buff = new byte[101];// 文件名长度不超过50 DatagramPacket dataPacket = new DatagramPacket(buff, buff.length); dataSocket.receive(dataPacket);// 等待接收来自客户端的数据包 // 接收到数据包,开一个线程为该客户服务 ThreadPool.execute(new WorkThread(dataPacket)); } } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // 内部类,为每个客户提供服务 private class WorkThread implements Runnable { private DatagramPacket packet; private DatagramSocket dataSocket; public WorkThread(DatagramPacket packet) { this.packet = packet; try {// 创建本机可以端口的DatagramSocket dataSocket = new DatagramSocket(); } catch (SocketException e) { e.printStackTrace(); } } // 获取可以下载的文件列表传送给客户端 private void showFiles() { File files = new File("upload_download"); File[] allFile = files.listFiles();// 获取所有文件 StringBuffer message = new StringBuffer(); for (File f : allFile) { if (f.isFile()) { message.append(f.getName()); message.append('\n'); } } // 构造响应数据包 byte[] response = message.toString().getBytes(); DatagramPacket dataPacket = new DatagramPacket(response, response.length, packet.getAddress(), packet.getPort()); try {// 发送 dataSocket.send(dataPacket); } catch (IOException e) { e.printStackTrace(); } } // 下载指定的文件 private void download(String fileName) { try { InputStream in = new FileInputStream("upload_download/" + fileName); DatagramPacket dataPacket; byte[] response = new byte[60000];// 每次发送60000字节 while (true) { int len = in.read(response, 0, response.length); dataPacket = new DatagramPacket(response, len, packet.getAddress(), packet.getPort()); dataSocket.send(dataPacket);// 发送 if (in.available() == 0)// 发送完毕 break; } in.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { // 获取客户端传送过来的数据 byte[] data = packet.getData(); // 表示客户端点击显示文件按钮,该请求是要得到所有可以下载的文件 if (data[0] == 0) showFiles(); else if (data[0] == 1)// 表示客户端的请求是下载请求 download(new String(data, 1, packet.getLength()).trim()); else System.out.println("请求错误"); } } public static void main(String[] args) { new DownloadServer().service(); } }
说明:DatagramSocket 类是基于UDP协议,服务器端默认提供下载的文件存放在当前目录下的upload_download文件夹中。服务器采用线程池能同时为多个用户服务
2、客户端代码
import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import javax.swing.*; /** * 下载客户端 */ public class DownloadClient extends JFrame { // 显示可下载的文件 private JTextArea textArea = new JTextArea(); private JPanel panel = new JPanel(); // 下载时保存文件 private JFileChooser saveFile = new JFileChooser("."); private JButton showButton = new JButton("显示文件"); private JButton downloadButton = new JButton("下载..."); // 下载时填入要下载的文件名,注意文件名必须是textArea显示的文件名 private JTextField downloadFile = new JTextField(""); private DatagramSocket dataSocket=null; public DownloadClient() { // frame 的基本设置 this.setTitle("下载客户端"); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(400, 500); this.setLayout(new BorderLayout()); this.setResizable(false); // 设置不可编辑 textArea.setEditable(false); panel.setLayout(new GridLayout(3, 2, 5, 5)); panel.add(new JLabel("点击按钮显示可下载的文件")); panel.add(showButton); panel.add(downloadFile); panel.add(downloadButton); // 组件加入frame中 add(new JScrollPane(textArea)); add(panel, BorderLayout.SOUTH); // saveFile只能打开目录 saveFile.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); // 显示文件按钮注册事件 showButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { showButton.setEnabled(false); downloadButton.setEnabled(false); showFiles(); showButton.setEnabled(true); downloadButton.setEnabled(true); } }); // 下载按钮注册事件 downloadButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { showButton.setEnabled(false); downloadButton.setEnabled(false); downloadFile(); showButton.setEnabled(true); downloadButton.setEnabled(true); } }); } // 显示文件 private void showFiles() { try { if (dataSocket == null) dataSocket = new DatagramSocket(); // 创建发送数据包并发送给服务器 byte[] request = { 0 }; DatagramPacket requestPacket = new DatagramPacket(request, request.length, InetAddress.getLocalHost(), 8289); dataSocket.send(requestPacket); // 接收服务器的数据包,显示在textArea中 byte[] receive = new byte[1024 * 1024]; DatagramPacket receivePacket = new DatagramPacket(receive, receive.length); dataSocket.receive(receivePacket); String str = new String(receivePacket.getData(), 0, receivePacket.getLength()); textArea.setText(str); } catch (IOException e) { e.printStackTrace(); } } // 下载文件 private void downloadFile() { // 获取要下载的文件名 String fileName = downloadFile.getText().trim(); // 所有可以下载的文件 String allFiles = textArea.getText(); // 文件名为空 if (fileName == null || "".equals(fileName)) JOptionPane.showMessageDialog(null, "请选中正确的文件名", "文件名错误", JOptionPane.WARNING_MESSAGE); // 文件名是在可以下载的文件中 else if (allFiles.contains((fileName + '\n'))) { saveFile.showSaveDialog(null); File f = saveFile.getSelectedFile();// 获取选中的文件夹 if (f.exists()) { // 检测该文件是否已经存在于目录中 String[] fileNames = f.list(); boolean exit = false; for (String name : fileNames) if (name.equals(fileName)) { exit = true; break; } if (exit)// 如果要下载的文件已经存在 JOptionPane.showMessageDialog(null, "此文件已经存在", "请选择另外的文件下载", JOptionPane.WARNING_MESSAGE); else { // 发送的请求 byte[] request = (new String(new byte[] { 1 }) + fileName).getBytes(); try { if (dataSocket == null) dataSocket = new DatagramSocket(); // 创建发送数据包并发送给服务器 DatagramPacket requestPacket = new DatagramPacket(request, request.length, InetAddress.getLocalHost(), 8289); dataSocket.send(requestPacket); // 接收服务器的数据包,把文件保存在选中的文件夹中 OutputStream out = new FileOutputStream(f.getAbsolutePath() + "/" + fileName, true); byte[] receive = new byte[60000];// 每次接收60000字节 DatagramPacket receivePacket; // 不断接收来自服务器的数据包 while (true) { receivePacket = new DatagramPacket(receive, receive.length); dataSocket.receive(receivePacket); out.write(receivePacket.getData(), 0, receivePacket.getLength());// 输出流把文件内容输出到文件中 out.flush(); if (receivePacket.getLength() != receive.length) break; } out.close(); } catch (IOException e) { e.printStackTrace(); } } } else // 选择的文件夹不存在 JOptionPane.showMessageDialog(null, "请选择正确的存储路径", "存储路径错误", JOptionPane.WARNING_MESSAGE); } else {// 文件名错误 JOptionPane.showMessageDialog(null, "请选择正确的文件名", "文件名错误", JOptionPane.WARNING_MESSAGE); } } public static void main(String[] args) { new DownloadClient(); } }
说明:客户端下载时先点击显示文件,然后输入要下载的文件名,最后点击下载按钮、选择保存路径
3、运行时先开服务器,然后再开客户端。运行结果:
点击显示文件按钮、输入01.jpg后:
点击下载按钮后、选择保存路径
点击保存按钮后,文件下载到指定目录下
0 0
- java网络编程六:DatagramSocket类简单实现文件下载
- java网络编程:DatagramSocket类简单实现文件下载
- DatagramSocket类简单实现文件下载
- DatagramSocket类简单实现文件下载
- java网络编程:DatagramSocket类
- DatagramSocket Java网络编程
- java 网络编程类 DatagramSocket,ServerSocket,Socket
- java中网络编程------UDP协议(实现步骤)DatagramSocket对象
- java网络编程-利用datagramsocket和datagrampacket实现一台机器向另一台机器传文件
- Java实现网络文件下载的简单示例
- java课内趣味小实验--DatagramSocket网络编程
- 黑马程序员--Java网络编程(InetAddress、DatagramSocket、DatagramPacket)
- Java 网络编程简单实现
- Android实现断点续传下载文件,网络编程
- 在Java中实现UDP协议编程(DatagramSocket/DatagramPacket)
- 在Java中实现UDP协议编程(DatagramSocket/DatagramPacket)
- JAVA---实现UDP协议编程(DatagramSocket/DatagramPacket)
- 在Java中实现UDP协议编程(DatagramSocket/DatagramPacket)
- 经典的BPN带动量的误差反向传播神经网络类代码示例
- WebView的使用
- "Android系统框架"-Androi的面试必问部分
- 推荐自用的WordPress插件
- Android基础--ActionBar的基本用法,自定义View,标题栏
- java网络编程:DatagramSocket类简单实现文件下载
- Android中的@SystemApi@hide等
- 蓝牙连接后,多个Activity应用
- 85-002-16 利用hibernate的级联功能实现(N+1)
- 使用nginx-rtmp搭建视频直播服务器
- 在Bluemix 使用OpenWhisk 开发Dark Vision应用系统
- Majority Element
- 从今天起开始学习Swift Hello,world
- spring mvc 框架搭建及详解