首页 > 解决方案 > 使用 Java Socket 和 java.nio.file.Files.copy 发送文件

问题描述

我正在尝试制作一个简单的服务器/客户端应用程序来发送消息和文件。

我的客户端首先发送文件名,然后是文件本身,最后等待服务器的响应。

我的服务器相反,读取文件名,读取文件,发送响应。

问题是客户端卡在String response = dataInputStream.readUTF(); 服务器卡在Files.copy(Paths.get(fileName), dataOutputStream);

我试图String response = dataInputStream.readUTF();从客户端中删除,没有它它可以正常工作。有人可以帮我理解为什么我readUtf()在发送文件后会卡住吗?

谢谢

这是我的客户

public static void main(String[] args) throws IOException {
    String fileName = "hello.txt";

    try (Socket clientSocket = new Socket(HOST, PORT)) {
        DataInputStream dataInputStream = new DataInputStream(clientSocket.getInputStream());
        DataOutputStream dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());

        dataOutputStream.writeUTF(fileName);

        Files.copy(Paths.get(fileName), dataOutputStream);

        String response = dataInputStream.readUTF();
        LOGGER.info(response);
    }
}

这是我的服务器

    public static void main(String args[]) throws IOException {

    try (ServerSocket ss = new ServerSocket(PORT)) {
        Socket clientSocket = ss.accept();

        DataOutputStream dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
        DataInputStream dataInputStream = new DataInputStream(clientSocket.getInputStream());

        String fileName = dataInputStream.readUTF();

        Files.copy(dataInputStream, Paths.get(fileName));

        dataOutputStream.writeUTF("New file saved");
    }
}

标签: javanioserversocketjava-io

解决方案


Here is my entire working sample of sending files from client to server. I am not sure particularly best when I was using Files.copy(...) on server I was getting stuck so you can check I have added boolean condition if the read is less that buffer size then there is no item present in the stream hence exit and close the file.

package com.company.socket;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

class SocketClient {
    public static void main(String[] args) {
        Thread clientThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try (Socket serverSocket = new Socket("localhost", 5000)) {
                    final DataOutputStream outputStream = new DataOutputStream(serverSocket.getOutputStream());
                    final BufferedReader br = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
                    Files.copy(Path.of("hello.txt"), serverSocket.getOutputStream());
                    outputStream.flush();
                    System.out.println("file sent from client");
                    String content = null;
                    while ((content = br.readLine()) != null) {
                        System.out.println("Client response: " + content);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        clientThread.start();

    }
}

public class SocketServer {
    public static void main(String[] args) throws InterruptedException, IOException {
        final Thread serverThread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Started server");
                List<Socket> clients = new ArrayList<>();
                Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("Server shutdown!");
                        final List<String> collect = clients.stream()
                                .map(socket -> {
                                    try {
                                        socket.close();
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                    return "Closed client: " + socket.getInetAddress().getHostAddress();
                                })
                                .collect(Collectors.toList());
                        collect.forEach(System.out::println);
                    }
                }));
                ServerSocket serverSocket = null;
                try {
                    serverSocket = new ServerSocket(5000);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                while (true) {
                    try (Socket client = serverSocket.accept()) {
                        clients.add(client);
                        System.out.println("CLient connected: " + client.getInetAddress().getHostAddress() + ":" + client.getPort());
                        client.getOutputStream().write("Hello from server!".getBytes());
                        client.getOutputStream().flush();
                        final InputStream inputStream = client.getInputStream();
                        System.out.println("copyingReceiving file on server");
                        copyFile(inputStream);
                        System.out.println("File received successfully");
                        client.getOutputStream().write("\nFile received successfully".getBytes());
                        client.getOutputStream().flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }

            void copyFile(InputStream inputStream) throws IOException {
                final byte[] buffer = new byte[2048];
                final FileOutputStream outputStream = new FileOutputStream("file-" + UUID.randomUUID().toString() + ".txt");
                int length = 0;
                while ((length = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, length);
                    outputStream.flush();
                    if (length < buffer.length) break;
                }
                outputStream.close();
            }
        });
        serverThread.start();

    }
}

Server output

Started server
CLient connected: 127.0.0.1:38118
copyingReceiving file on server
File received successfully

Client output

file sent from client
Client response: Hello from server!
Client response: File received successfully


推荐阅读