Java使用Socket远程发送文件

客户端和服务器交互

基于TCP的网络传输(基于TCP的Socket传输) 

传输字符串的小例子:

  • 服务端发布一个服务需要绑定端口,每个软件都需要暴露一个端口(MySQL:3306, Oracle:1521),服务器上有很多软件,外界如何定位到具体的软件呢?答案就是:端口号。

  • 服务器端绑定端口,绑定之后,客户端就可以访问该服务。
ServerSocket(端口号9999)
  • 客户端访问服务,通过如下方式:
Scoket("服务器ip", 端口号9999)

  这样服务器和客户端就建立起了双向连接

  • 服务器是如何直到客户端发起了连接?答案:服务器端通过ServerSocket的accept()方法进行监听是否有客户端访问。
  • 当服务器监听到客户端的访问,也就是连接建立之后,服务器和客户端就可以进行通信了。

         (客户服务器通信模型) 

代码实现简单的客户端和服务器传送消息:

服务器端代码实现:

public class Server {
    @Test
    public void serverTest() throws IOException {
        // 1. 绑定服务端口号,暴露一个服务,该服务的地址是:本机IP:9999
        ServerSocket serverSocket = new ServerSocket(9999);
        // 2. 监听是否有客户端访问
        // 如果没有客户端访问,则会阻塞,直到有客户端进行访问,才会向下执行
        Socket socket = serverSocket.accept();
        System.out.println("与客户端成功建立连接");
        // 3. 获取输出流,向客户端发送消息
        OutputStream outputStream = socket.getOutputStream();

        outputStream.write("你好啊".getBytes());

        System.out.println("------------------------ 下面是服务器接受客户端发送的消息------------------------------");

        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[1024];
        inputStream.read(bytes);
        System.out.println("客户端发送的消息是 : " + new String(bytes));
        // 4. 关闭连接
        inputStream.close();
        outputStream.close();
        socket.close();
        serverSocket.close();

    }
}

客户端实现代码:

public class Client {

    @Test
    public void clientTest() throws IOException {
        // 1. 客户端连接服务器Server发布的服务
        Socket socket = new Socket("127.0.0.1", 9999);
        InputStream inputStream =
                socket.getInputStream();
        byte[] bytes = new byte[1024];
        inputStream.read(bytes);
        System.out.println(new String(bytes));

        System.out.println("------------------------ 下面是客户端向服务器发送消息------------------------------");

        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("server, 你好".getBytes());
        outputStream.close();
        inputStream.close();
        socket.close();

    }
}

输出结果:

客户端:

你好啊                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
------------------------ 下面是客户端向服务器发送消息------------------------------

Process finished with exit code 0

服务器端输出:

与客户端成功建立连接
------------------------ 下面是服务器接受客户端发送的消息------------------------------
客户端发送的消息是 : server, 你好                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  

Process finished with exit code 0

服务器向客户端发送文件的例子:

服务器端代码实现:

public class FileServer {
    @Test
    public void fileServerTest() throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);

        Socket socket = serverSocket.accept();

        System.out.println("与客户端建立连接!");
        // 将文件内容从硬盘读入内存中
        FileInputStream fileInputStream = new FileInputStream("data/hello.txt");
        OutputStream outputStream = socket.getOutputStream();
        // 定义每次发送文件的大小
        byte[] buffer = new byte[256];
        int len = 0;
        // 因为文件内容较大,不能一次发送完毕,因此需要通过循环来分次发送
        while ((len = fileInputStream.read(buffer)) != -1){
            outputStream.write(buffer, 0, len);
        }

        outputStream.close();
        fileInputStream.close();
        socket.close();
        serverSocket.close();

    }
}

客户端代码实现:

public class FileClient {
    @Test
    public void fileClientTest() throws IOException {
        Socket socket = new Socket("127.0.0.1", 9999);

        FileOutputStream fileOutputStream = new FileOutputStream("data/out.txt");

        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[256];
        int len = 0;
        while ((len = inputStream.read(bytes)) != -1){
            fileOutputStream.write(bytes, 0, len);
        }
        inputStream.close();
        fileOutputStream.close();
        socket.close();
    }
}

上述代码,只能实现客户端和服务器端一次文件传输,如果我们想要从客户端向服务器多次发送文件,该怎么实现呢?

服务器端代码实现:

public class ServerReciveFile {
    @Test
    public void serverReciveFileTest() throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);
        while (true){
            Socket socket = serverSocket.accept();

            System.out.println("与客户端建立连接!");
            // 将文件内容从硬盘读入内存中
            FileInputStream fileInputStream = new FileInputStream("data/hello.txt");
            OutputStream outputStream = socket.getOutputStream();
            // 定义每次发送文件的大小
            byte[] buffer = new byte[256];
            int len = 0;
            // 因为文件内容较大,不能一次发送完毕,因此需要通过循环来分次发送
            while ((len = fileInputStream.read(buffer)) != -1){
                outputStream.write(buffer, 0, len);
            }

            outputStream.close();
            fileInputStream.close();
            socket.close();
        }

        // serverSocket.close(); // 服务器常开,因而不需要进行关闭
    }
}

客户端代码实现:

public class ClientSendFile {

    @Test
    public void clientSendFileTest() throws IOException {
        Socket socket = new Socket("127.0.0.1", 9999);

        FileOutputStream fileOutputStream = new FileOutputStream("data/out1.txt");

        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[256];
        int len = 0;
        while ((len = inputStream.read(bytes)) != -1){
            fileOutputStream.write(bytes, 0, len);
        }
        inputStream.close();
        fileOutputStream.close();
        socket.close();
    }
}

使用多线程实现从客户端向服务器多次发送文件:

服务器端代码实现:

public class MultiThreadServer {

    @Test
    public void multiThreadServerTest() throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);

        while (true){
            Socket socket = serverSocket.accept();

            Thread downloadThread = new Thread(new ClientThread(socket));
            downloadThread.start();
        }
    }
}

class ClientThread implements Runnable{
    private Socket socket;

    public ClientThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            OutputStream outputStream = socket.getOutputStream();
            FileInputStream fileInputStream = new FileInputStream("data/hello.txt");
            byte[] buffer = new byte[256];
            int len = 0;
            while ((len = fileInputStream.read(buffer)) != -1){
                outputStream.write(buffer, 0, len);
            }
            outputStream.close();
            fileInputStream.close();
            socket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 客户端代码实现:

public class MultiThreadClient {

   @Test
   public void multiThreadClientTest() throws IOException {
       Socket socket = new Socket("127.0.0.1", 9999);

       InputStream inputStream = socket.getInputStream();
       FileOutputStream fileOutputStream = new FileOutputStream("data/out3.txt");
       byte[] buffer = new byte[256];
       int len = 0;
       while ((len = inputStream.read(buffer)) != -1){
           fileOutputStream.write(buffer, 0, len);
       }
       fileOutputStream.close();
       inputStream.close();
       socket.close();
   }
}

至此,Java使用Socket远程发送文件介绍结束。

猜你喜欢

转载自blog.csdn.net/kaizuidebanli/article/details/84311921