使用多个IO流通过java套接字进行文件传输

使用多个IO流通过java套接字进行文件传输,java,multithreading,sockets,file-transfer,large-files,Java,Multithreading,Sockets,File Transfer,Large Files,最近,我编写了一个简单的客户机-服务器程序,用于通过标准TCP套接字进行文件传输。WiFi信道的平均吞吐量约为2.2Mbps。我的问题是: 是否可以在多个数据IO流上传输一个大文件(比如5GB),以便每个流可以并行地传输同一文件的多个部分(可以使用不同的线程)?这些文件部件可以在接收端重新组装。 我试图分割一个小文件并通过dataoutputstream传输它。第一段工作正常,但我不知道如何以选择性方式读取文件输入流(我还尝试了mark()和reset()方法进行选择性读取,但没有用) 以下是我

最近,我编写了一个简单的客户机-服务器程序,用于通过标准TCP套接字进行文件传输。WiFi信道的平均吞吐量约为2.2Mbps。我的问题是: 是否可以在多个数据IO流上传输一个大文件(比如5GB),以便每个流可以并行地传输同一文件的多个部分(可以使用不同的线程)?这些文件部件可以在接收端重新组装。 我试图分割一个小文件并通过dataoutputstream传输它。第一段工作正常,但我不知道如何以选择性方式读取文件输入流(我还尝试了mark()和reset()方法进行选择性读取,但没有用)

以下是我的代码(出于测试目的,我已将输出重定向到fileoutputstream):


任何帮助都将不胜感激!提前谢谢

您可以获取
文件输入流的字节数组
,并将其每10 KB(每10.000字节)拆分一次。 然后按顺序通过流发送这些部分


在服务器上,您可以再次将数组放在一起,然后从这个大字节数组中读取文件。

您可以获取
文件输入流的字节数组,并将其每10 KB(每10.000字节)拆分一次。
然后按顺序通过流发送这些部分


在服务器上,您可以再次将阵列放在一起,然后从这个大字节阵列读取文件。

使用更多套接字,在同一个链接上无法获得更高的速度。每个套接字发送一定数量的数据包,每个数据包具有一定的大小。当我们将套接字的数量增加一倍时,每秒*套接字的数据包数量减少了一半,然后由于冲突、开销和争用而进一步减少。数据包开始颠簸、混乱,或者出现恐慌。操作系统无法处理丢失确认的混乱局面,WiFi卡难以以这样的速率传输。它也正在失去它的低级ACK。当数据包丢失时,一个绝望的TCP堆栈会降低传输速率。如果这是由于信号改善而出现的,那么由于愚蠢的窗口综合症或另一种形式的TCP死锁,它现在只能以较低的速度运行

任何试图从更宽的载波频带、MiMo或多条路径中获得更高速度的WiFi都已经实现了增益,即使只有一个插座。你不能再往前走了

现在,等等。我们的无线网络速度很低,不是吗?当然,我们需要使用缓冲


确保从套接字的getInputStream或getOutputStream方法创建BufferedWriter和BufferedReader对象。然后写入/读取这些缓冲区。您的速度可能会有所提高。

使用更多套接字的同一链路无法获得更多的速度。每个套接字发送一定数量的数据包,每个数据包具有一定的大小。当我们将套接字的数量增加一倍时,每秒*套接字的数据包数量减少了一半,然后由于冲突、开销和争用而进一步减少。数据包开始颠簸、混乱,或者出现恐慌。操作系统无法处理丢失确认的混乱局面,WiFi卡难以以这样的速率传输。它也正在失去它的低级ACK。当数据包丢失时,一个绝望的TCP堆栈会降低传输速率。如果这是由于信号改善而出现的,那么由于愚蠢的窗口综合症或另一种形式的TCP死锁,它现在只能以较低的速度运行

任何试图从更宽的载波频带、MiMo或多条路径中获得更高速度的WiFi都已经实现了增益,即使只有一个插座。你不能再往前走了

现在,等等。我们的无线网络速度很低,不是吗?当然,我们需要使用缓冲


确保从套接字的getInputStream或getOutputStream方法创建BufferedWriter和BufferedReader对象。然后写入/读取这些缓冲区。您的速度可能会有所提高。

如果您试图通过同一WiFi通道传输更多数据,则速度可能会变慢,因为每个插座都会增加对其他插座的争夺。+1到@1。问题是什么是限制因素。“我怀疑(比如@hex)你受到wifi速度的限制,因为其他连接将在同一个wifi通道上,它们将无法并行工作。”格雷作为答案发布。嗯,这很令人失望。。我对socket编程还不熟悉,所以只想探索一下。谢谢你宝贵的信息,顺便说一句!您能推荐一些通过java套接字进行文件传输的优化技术吗?使用dataoutputstream而不是文件通道可以吗?@VinitShandilya您的限制仍然存在于链接上(假设您使用
BufferedWriter
。如果您试图在同一WiFi通道上传输更多数据,则速度可能会变慢,因为每个套接字都会增加对其他套接字的争用。+1到@hexafraction。问题是限制因素是什么。我怀疑(比如@hex)“你受到wifi速度的限制,而且由于其他连接将在同一wifi通道上,它们将无法并行工作。”格雷作为答案发布。好吧,这很令人失望。我对套接字编程不熟悉,所以只想探索一下。谢谢你宝贵的信息,顺便说一句!你能建议一些优化方法吗?”n通过java套接字进行文件传输的技术?使用dataoutputstream而不是文件通道可以吗?@VinitShandilya您的限制仍然存在于链接上(假设您使用的是
BufferedWriters
.10KB!=10000bytest这不会带来更高的吞吐量,只会带来更复杂的代码。好吧……然后每10240拆分一次bytes@BackSlash10KB=10000字节。10KB=10240字节。该数字有效,但仍然不会有更高的吞吐量。10KB!=10000BYTEST这不会导致更高的吞吐量,只是更多复杂的代码。好吧……然后每10240分一次bytes@BackSlash10KB=10000字节。10KB=10240字节。该数字是有效的,尽管仍然不会有更高的吞吐量
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    final File myFile=new File("/home/evinish/Documents/Android/testPicture.jpg");
    long N=myFile.length();
    try {
        FileInputStream in=new FileInputStream(myFile);
        FileOutputStream f0=new FileOutputStream("/home/evinish/Documents/Android/File1.jpg");
        FileOutputStream f1=new FileOutputStream("/home/evinish/Documents/Android/File2.jpg");
        FileOutputStream f2=new FileOutputStream("/home/evinish/Documents/Android/File3.jpg");

        byte[] buffer=new byte[4096];
        int i=1, noofbytes;
        long acc=0;
        while(acc<=(N/3)) {
            noofbytes=in.read(buffer, 0, 4096);
            f0.write(buffer, 0, noofbytes);
            acc=i*noofbytes;
            i++;
        }
        f0.close();
    package com.mergefilespackage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class MergeFiles {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception{
        // TODO Auto-generated method stub
        IOCopier.joinFiles(new File("/home/evinish/Documents/Android/File1.jpg"), new File[] {
            new File("/home/evinish/Documents/Android/File2.jpg"), new File("/home/evinish/Documents/Android/File3.jpg")});
    }
}
class IOCopier {
    public static void joinFiles(File destination, File[] sources)
            throws IOException {
        OutputStream output = null;
        try {
            output = createAppendableStream(destination);
            for (File source : sources) {
                appendFile(output, source);
            }
        } finally {
            IOUtils.closeQuietly(output);
        }
    }

    private static BufferedOutputStream createAppendableStream(File destination)
            throws FileNotFoundException {
        return new BufferedOutputStream(new FileOutputStream(destination, true));
    }

    private static void appendFile(OutputStream output, File source)
            throws IOException {
        InputStream input = null;
        try {
            input = new BufferedInputStream(new FileInputStream(source));
            IOUtils.copy(input, output);
        } finally {
            IOUtils.closeQuietly(input);
        }
    }
}
class IOUtils {
    private static final int BUFFER_SIZE = 1024 * 4;

    public static long copy(InputStream input, OutputStream output)
            throws IOException {
        byte[] buffer = new byte[BUFFER_SIZE];
        long count = 0;
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
            count += n;
        }
        return count;
    }

    public static void closeQuietly(Closeable output) {
        try {
            if (output != null) {
                output.close();
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}