Java 套接字卡在 readUTF() 上

Java socket is stuck on readUTF()

我正在尝试通过 Java 中的套接字传输文件,我目前的服务器方法是:

  1. 创建新话题
  2. 线程使用dos.writeUTF()
  3. 发送文件名
  4. 线程使用dos.writeLong()
  5. 发送文件大小
  6. 线程使用dos.write()
  7. 发送文件

其中每个线程代表一个客户端,dos 是 DataOutputStream 的一个实例。

现在,我在客户端上做同样的事情,但阅读而不是写作:

  1. 使用dis.readUTF()
  2. 读取文件名
  3. 使用dis.readLong()
  4. 读取文件大小
  5. 使用dis.read()
  6. 读取文件

其中 dis 是 DataInputStream 的实例。
问题是:发送一个文件时,一切正常,但是当我尝试一个接一个地发送 3 个文件时,看起来服务器正在按预期将所有内容正确写入流,但客户端(在第一个文件之后,意味着这从第二个文件开始发生)卡在 dis.readUTF() 上,无法继续。

我已经尝试修复此问题好几天了,但无法正常工作。
这是源代码:

服务器:

Main.java

 public class Main {
    public static void main(String[] args) {
        boolean boolDebug = true;//TODO REMOVE THIS!!
        ServerSocket serverSock = null;
        List<Socket> clientSocks;
        List<ClientThread> clientThreads;
        try {
            serverSock = new ServerSocket(9090);
        } catch(Exception e){
            e.printStackTrace();
        }
        clientSocks = new ArrayList<>();
        clientThreads = new ArrayList<>();
        ServerSocket finalServerSock = serverSock;

        System.out.println();
        System.out.println("Listening for incoming connections\n");
        new Thread(){
            @Override
            public void run() {
                super.run();
                while (true) {
                    try {
                        Socket newSock = finalServerSock.accept();
                        clientSocks.add(newSock); //FIXME Remove sockets when closed
                        Thread thread = new ClientThread(newSock, usr, psw);
                        thread.start();
                        clientThreads.add((ClientThread)thread);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }
}

ClientThread.java

public class ClientThread extends Thread {
    private Socket socket;
    private DataInputStream inStream;
    private DataOutputStream outStream;
    private String dbUser;
    private String dbPassword;

    public ClientThread(Socket socket, String DbUser, String DbPass) {
        this.socket = socket;
        this.dbUser = DbUser;
        this.dbPassword = DbPass;
    }

    @Override
    public void run() {
        try {
            inStream = new DataInputStream(socket.getInputStream());
            outStream = new DataOutputStream(socket.getOutputStream());
            sendFile("a.txt");
            sendFile("b.txt");
            sendFile("c.txt");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    void sendFile(String file){
        try {
            File f = new File(file);
            outStream.writeUTF(file);
            outStream.writeLong(f.length());
            FileInputStream fis = new FileInputStream(f);
            byte[] buffer = new byte[4096];

            while (fis.read(buffer) > 0) {
                outStream.write(buffer);
            }
            fis.close();
        }catch(Exception e){
            e.printStackTrace();
        }

    }
    int getSize(byte[] buffer,long remaining){
        try {
            return Math.toIntExact(Math.min(((long) buffer.length), remaining));
        }catch(ArithmeticException e){
            return 4096;
        }
    }

}

客户: Main.java

class Main {

    static int getSize(byte[] buffer, long remaining) {
        try {
            return Math.toIntExact(Math.min(((long) buffer.length), remaining));
        } catch (ArithmeticException e) {
            return 4096;
        }
    }

    static void saveFile(Socket clientSock,DataInputStream dis) throws IOException {

        String fileName = dis.readUTF();
        File f = new File(fileName);
        FileOutputStream fos = new FileOutputStream(f);
        byte[] buffer = new byte[4096];

        long filesize = dis.readLong();
        int read = 0;
        int totalRead = 0;
        long remaining = filesize;

        while ((read = dis.read(buffer, 0, getSize(buffer, remaining))) > 0) {
            totalRead += read;
            remaining -= read;
            System.out.println("read " + totalRead + " bytes.");
            fos.write(buffer, 0, read);
        }
        fos.close();
    }

    public static void main(String[] args) throws Exception {
        Socket sock = new Socket("192.168.2.17", 9090);
        DataInputStream dis = new DataInputStream(sock.getInputStream());
        saveFile(sock,dis);
        saveFile(sock,dis);
        saveFile(sock,dis);

    }
}

非常感谢,期待解决此问题:(

通过更改

修复
while (fis.read(buffer) > 0) {
    outStream.write(buffer);
}

int count;
while ((count = fis.read(buffer)) > 0) {
    outStream.write(buffer, 0, count);
}

服务器端ClientThread.java内部