【问题标题】:Why Client B didn't get complete file为什么客户端 B 没有得到完整的文件
【发布时间】:2012-11-30 17:58:17
【问题描述】:

我正在尝试在 2 个 Java 套接字客户端之间建立文件传输机制。发件人客户端将包括此排序 sn-p:

    FileInputStream fis = null;
    BufferedInputStream bis = null;
    BufferedOutputStream outStream = null;
    byte[] fileBytes = new byte[(int) file.length()];
    int bytesRead = 0;

    try {
        fis = new FileInputStream(file);
        bis = new BufferedInputStream(fis);
        outStream = new BufferedOutputStream(socket.getOutputStream());
        bytesRead = bis.read(fileBytes, 0, fileBytes.length);
        outStream.write(fileBytes, 0, fileBytes.length);

    } catch (IOException _IOExc) {
        Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, 
            null, _IOExc);
        //QuitConnection(QUIT_TYPE_DEFAULT);
    } 

服务器中介看起来像:

public void run() {
    assert (outSocket != null);
    byte[] bytes = new byte[fileSize];
    try {
        System.out.println("inStream " + inStream.available());
        outStream = new BufferedOutputStream(outSocket.getOutputStream());
        inStream.read(bytes, 0, fileSize);
        outStream.write(bytes, 0, fileSize);
        outStream.flush();

    } catch (IOException ex) {
        Logger.getLogger(FileTransport.class.getName()).log(Level.SEVERE, 
            null, ex);
    }
  }

目标客户端:

    public void run() {
        try {
            System.out.println("Start reading...");
            int len = 1024;
            BufferedInputStream inStream = new BufferedInputStream 
                  (client.user.getClientSocket().getInputStream());
            while ((bytesRead = inStream.read(fileBytes, 0, len)) > 
                  0 && current < fileSize) {
                current = current + bytesRead;
                System.out.println("current "+ current);
                bos.write(fileBytes, 0, bytesRead < len ? bytesRead : len);
            }
            bos.flush();
            bos.close();
        } catch (IOException ex) {
            Logger.getLogger(ReadFileThread.class.getName()).log(Level.SEVERE, 
                null, ex);
        } catch (InterruptedException e) {
        }
    }

服务器和目标客户端都提前传递了“fileSize”,现在的问题是服务器端获取的数据略少,客户端B一直从服务器读取8192字节的数据,永远无法退出循环。

非常感谢 凯夫

【问题讨论】:

  • 试试 byte[] fileBytes = new byte[fis.availible()];也许 file.length() 返回一个错误的值。为什么你需要转换为 int 呢?文件是文件对象吗?还是字符串?
  • file.length 通常返回 Long.... 读取和发送文件是好的。我只是想知道服务器端
  • 哦,所以文件是一个文件对象?你试过 fis.availible() 吗?
  • 还没有,但我不认为这种投射会导致精度出错。看起来clientB无法从服务器获取全部数据。没看到你在 clientB 上与 inputStream 竞争
  • 痛苦的是服务器端打印 inStream.read(bytes, 0, fileSize) 永远不会返回相同的结果!!!

标签: java swing network-programming thread-safety swingworker


【解决方案1】:

不要忽略read() 方法的结果。它返回已读取的字节数,不一定是文件的长度。 read() 必须始终在循环中调用,直到它返回 -1。

永远不要使用available()。它不会返回您认为它返回的内容。只需循环直到read() 返回 -1 或直到读取的字节数达到预期计数。

阅读the IO tutorial

【讨论】:

  • outputStream.flush() 怎么样,应该在 outputStream.write() 之后的循环内吗?
  • 当您想让缓冲的流将其缓冲区的内容发送到其包装的流时,您会刷新。通常,当您没有任何内容要写入流时。
  • 嗯.. 服务器端 read() 看起来不会得到 -1,每次总字节聚合不同。当客户端 A 上的字节发送正常时,怎么会发生这种情况
  • 然后读取直到获得预期的字节数。只是不要期望在一次调用read() 中读取字节。这就是 TCP 和流的工作方式。即使您在客户端的一次调用中写入 1MB,也可能需要在服务器端 100 read() 才能读取它们。
猜你喜欢
  • 1970-01-01
  • 2010-12-29
  • 1970-01-01
  • 2018-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-20
相关资源
最近更新 更多