案例 1

要求:

  • 编写客户端程序和服务器端程序;
  • 客户端可以输入一个音乐文件名,比如“高山流水”,服务端收到音乐名后,可以给客户端返回这个音乐文件,如果服务器本地没有这个文件,返回一个默认的音乐即可。;
  • 客户端接收到文件后,保存到本地;

本质:其实就是指定下载文件的应用,可以结合文件上传来做

Server 端 - 提供文件下载服务

  1. package Atest;
  2. import java.io.*;
  3. import java.net.ServerSocket;
  4. import java.net.Socket;
  5. public class Server {
  6. public static void main(String[] args) throws Exception {
  7. // 监听 9999 端口
  8. int port = 9999;
  9. ServerSocket serverSocket = new ServerSocket(port);
  10. // 等待客户端连接后发送下载文件的名称
  11. Socket socket = serverSocket.accept();
  12. // 读取客户端要下载的文件名
  13. InputStream inputStream = socket.getInputStream();
  14. String downloadFileName = null;
  15. byte[] buffer = new byte[1024];
  16. int len = 0;
  17. while ((len = inputStream.read(buffer)) != -1) {
  18. downloadFileName = new String(buffer, 0, len);
  19. }
  20. System.out.println("客户端需要下载的文件:" + downloadFileName);
  21. // 服务器上有两个文件, 无名.mp3 高山流水.mp3
  22. // 如果客户端下载的是高山流水,就返回该文件,否则一律返回 无名.mp3
  23. String resFilePath = "";
  24. if ("高山流水".equals(downloadFileName)) {
  25. resFilePath = "./高山流水.mp3";
  26. } else {
  27. resFilePath = "./无名.mp3";
  28. }
  29. // 创建一个输入流,读取文件到输入流对象中
  30. BufferedInputStream bis = new BufferedInputStream(new FileInputStream(resFilePath));
  31. byte[] bytes = streamToByteArray(bis);
  32. // 得到 socket 关联的输出流
  33. BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
  34. // 写入到数据通道,返回给客户端
  35. bos.write(bytes);
  36. socket.shutdownOutput();
  37. // 关闭相关的资源
  38. bis.close();
  39. bos.close();
  40. socket.close();
  41. serverSocket.close();
  42. System.out.println("服务端退出");
  43. }
  44. public static byte[] streamToByteArray(InputStream is) throws Exception {
  45. // 创建输出流对象
  46. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  47. byte[] buffer = new byte[1024];
  48. int len = 0;
  49. while ((len = is.read(buffer)) != -1) {
  50. bos.write(buffer, 0, len);
  51. }
  52. byte[] bytes = bos.toByteArray();
  53. bos.close();
  54. return bytes;
  55. }
  56. }

Client 端 - 下载者

package Atest;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) throws Exception {
        // 接收用户输入,指定下载文件名
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入下载文件名:");
        String downloadFileName = sc.next();

        // 客户端连接服务器,准备发送文件名给服务器
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        // 获取 socket 相关的输出流
        OutputStream os = socket.getOutputStream();
        os.write(downloadFileName.getBytes());
        socket.shutdownOutput();

        // 读取服务端返回的文件(字节数据)
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        byte[] bytes = streamToByteArray(bis);
        // 得到一个输出流,准备将 byte[] 数组写入到磁盘文件
        String filePath = "./" + downloadFileName + "_download.mp3";
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
        bos.write(bytes);

        // 关闭相关资源
        bos.close();
        bis.close();
        os.close();
        socket.close();

        System.out.println("客户端下载完毕");

    }

    public static byte[] streamToByteArray(InputStream is) throws Exception {
        // 创建输出流对象
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        byte[] buffer = new byte[1024];
        int len = 0;

        while ((len = is.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        byte[] bytes = bos.toByteArray();
        bos.close();

        return bytes;
    }
}