【问题标题】:Sending large files (~ 1GB) fails with SocketException发送大文件 (~ 1GB) 失败并出现 SocketException
【发布时间】:2013-05-23 17:37:08
【问题描述】:

我正在尝试使用 java 中的套接字编程为 p2p 文件共享应用程序发送大文件。此代码发送 200-300 mb 文件没有任何问题,但对于 1 gb 左右的大文件,它会给出错误:-

    java.net.SocketException: Software caused connection abort: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
    at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
    at FileSender.main(FileSender.java:28)

按照我得到的许多答案中的建议,我已经在小块发送文件。我应该怎么做才能发送 1 GB 的文件。我在 Windows 上编程。

这是我的代码:

服务器

public class FileSender {
    public static void main(String...s)
    {
        BufferedOutputStream bos;
        String file="D:\\filename.mp4";

        try {
            ServerSocket sock=new ServerSocket(12345);      
            while(true)
            {   
                System.out.println("waiting");
                Socket soc=sock.accept();
                bos= new BufferedOutputStream(soc.getOutputStream());
                FileInputStream fis = new FileInputStream(file);
                BufferedInputStream bis = new BufferedInputStream(fis);
                int n=-1;
                byte[] buffer = new byte[8192];
                while((n = bis.read(buffer))>-1) 
                { 
                    bos.write(buffer,0,n);
                    System.out.println("bytes="+n);
                    bos.flush();
                }
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

接收者

public class FileReciev {
    public static void main(String...s)
    {
        try    
        {      
            Socket sock=new Socket("127.0.0.1",12345);
            File file=new File("D:\\newfilename.mp4");
            BufferedInputStream bis=new BufferedInputStream(sock.getInputStream());
            FileOutputStream fos = new FileOutputStream(file);
            int n;
            byte[] buffer = new byte[8192];
            System.out.println("Connected");
            while ((n = bis.read(buffer)) > -1) {
                System.out.println("bytes="+n);
                fos.write(buffer, 0, n);
                if(n<(8192)){
                    fos.close();
                    bis.close();
                    break;
                } 
                fos.flush();
            }

            System.out.println("recieved");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

【问题讨论】:

  • 很可能接收方与服务器不同步,即接收方无法在服务器发送另一个数据包的时间内读取所有数据。
  • 你可以实现一个阻塞机制,这样服务器就不会发送新数据,因为接收者已经读取了所有之前发送的数据。
  • @ExtremeCoders TCP 已经做到了。
  • 不要在循环内刷新。这样做会失去缓冲输出流的所有好处。

标签: java sockets networking large-files file-handling


【解决方案1】:
if(n<(8192)){
    fos.close();
    bis.close();

这意味着如果您曾经获得的字节数少于您预期的字节数,您将关闭您的套接字。没有理由这样做。

【讨论】:

  • 那么如何在不知道文件大小的情况下停止连接...??
  • 您的循环已经在流结束时终止。这就是你所需要的。完全删除这段代码即可。
  • 即使在删除该块文件后完全传输但循环没有结束,它卡住了。它只是在等待另一个块读取。接收方最后打印“received”,但没有打印“received”。
  • 我没有关闭发送方的流,所以接收方仍在等待......!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
  • 2018-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多