【问题标题】:Sending Files Through Stream通过流发送文件
【发布时间】:2012-04-24 15:41:52
【问题描述】:

这是我现在拥有的。

接收者:

public static void read(Socket socket, ObjectInputStream in) {
    try {
        String separator = in.readUTF();
        while (in.readByte() == -3) {
            String path = in.readUTF().replaceAll(separator, System.getProperty("file.separator"));
            File file = new File(new File(path).getParent());
            if (!file.exists()) {
                file.mkdirs();
            }
            FileOutputStream fos = new FileOutputStream(path);
            int b = 0;
            while ((b = in.readByte()) != -4) {
                fos.write(b);
            }
            fos.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

发件人:

public static void send(String[] path) {
    Socket socket;
    try {
        socket = new Socket(ip, port);
        socket.setKeepAlive(true);
    } catch (UnknownHostException e) {
        return;
    } catch (IOException e) {
        return;
    }
    try {
        ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
        out.writeUTF(Devbox.getSeparator());
        for (String s : path) {
            send(s, out);
            out.writeByte(-2);
        }
        out.close();
        socket.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private static void send(String path, ObjectOutputStream out) {
    File file = new File(path);
    if (file.isDirectory()) {
        File[] files = file.listFiles();
        for (File f : files) {
            send(path + f.getName(), out);
        }
    } else {
        try {
            out.writeByte(-3);
            out.writeUTF(path);
            FileInputStream fis = new FileInputStream(file);
            int b = 0;
            while ((b = fis.read()) != -1) {
                out.writeByte(b);
            }
            fis.close();
            out.writeByte(-4);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这是我在发件人中遇到的错误。

java.net.SocketException: Software caused connection abort: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
    at java.io.ObjectOutputStream$BlockDataOutputStream.writeBlockHeader(ObjectOutputStream.java:1874)
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1855)
    at java.io.ObjectOutputStream$BlockDataOutputStream.writeByte(ObjectOutputStream.java:1895)
    at java.io.ObjectOutputStream.writeByte(ObjectOutputStream.java:760)

它指向

                out.writeByte(b);

它成功发送了大约 25 个文件,然后抛出此错误。每次它扔到的文件都不一样,但在5个文件左右的相同范围内。接收方在一个特定文件之后停止,该文件通常在发送方停止的文件之前一对。它停止是因为 in.readByte() == -3 是假的。当它发生时,我得到了 -85 和 16 之类的数字。我在另一台计算机上尝试了它,因为它说的是软件,它是完全相同的。有谁知道为什么会这样?我花了一天的时间试图弄清楚,但一无所获。非常感谢任何帮助。

【问题讨论】:

  • 你能保证你的输入文件不包含值 -4 吗?否则,接收方停止向输出文件写入字节(甚至可能关闭连接?),而发送方仍在向流中写入数据。
  • @AndreHolzner 是的,我可以保证这不是问题。

标签: java stream network-programming


【解决方案1】:

请阅读此answer,除此之外我不认为还有什么可以说的,我也没有在您的代码中看到任何会关闭连接的内容。

来自 OTN 讨论

WinSock 说明:本地网络系统时会出现该错误 中止连接。如果 WinSock 中止已建立的 数据重传失败后连接(接收方从不 确认在数据流套接字上发送的数据)。

TCP/IP 场景:如果本地系统没有连接,连接将超时 接收已发送数据的 (ACK) 确认。如果一个 (FIN)ish TCP 数据包没有被 ACK(即使 FIN 被 ACK,它 如果没有返回 FIN,最终会超时)。

在 WindowsXP 上似乎发生得更多,而且似乎也是 可能与 Windows 防火墙设置有关。在任何情况下,突出 关键是中止起源于本地机器内部。

【讨论】:

  • 如果是这种情况,有什么办法可以解决吗?
【解决方案2】:

使用 BufferedInputStream 在 send 方法中读取 FileInputStream。

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
while ((b = bis.read()) != -1) {
    out.writeByte(b);
}

也可以试试互补的 BufferedOutputStream

BufferedInputStream bos = new FileOutputStream(path);
int b = 0;
while ((b = in.readByte()) != -4) {
    bos.write(b);
}

此外,您需要在文件完成传输时清除连接。

out.flush;

【讨论】:

  • 它做同样的事情,但没有帮助。
  • 您可能需要在接收器的读取方法上使用补充的 BufferedOutputStream。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-01
  • 1970-01-01
  • 2015-07-14
  • 2012-09-16
  • 2015-01-26
相关资源
最近更新 更多