带套接字的大文件传输

时间:2011-02-25 05:23:55

标签: java sockets network-programming client

当我使用套接字编程传输大文件时,收到的文件不完整,即它是一个mp3文件,当我播放时听起来很奇怪。 代码是:

服务器端:

File myFile = new File("abc.mp3");
{
    Socket sock = servsock.accept();
    int packetsize=1024;
    double nosofpackets=Math.ceil(((int) myFile.length())/packetsize);
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
    for(double i=0;i<nosofpackets+1;i++) {
        byte[] mybytearray = new byte[packetsize];
        bis.read(mybytearray, 0, mybytearray.length);
        System.out.println("Packet:"+(i+1));
        OutputStream os = sock.getOutputStream();
        os.write(mybytearray, 0,mybytearray.length);
        os.flush();
    }
}

客户端:

int packetsize=1024;
FileOutputStream fos = new FileOutputStream("zz.mp3");
BufferedOutputStream bos = new BufferedOutputStream(fos);
double nosofpackets=Math.ceil(((int) (new File("abc.mp3")).length())/packetsize);
for(double i=0;i<nosofpackets+1;i++)
{
    InputStream is = sock.getInputStream();
    byte[] mybytearray = new byte[packetsize];
    int bytesRead = is.read(mybytearray, 0,mybytearray.length );
    System.out.println("Packet:"+(i+1));
    bos.write(mybytearray, 0,mybytearray.length);
}
sock.close();
bos.close();

在客户端,我使用new File("abc.mp3")).length只是为了简单起见(我可以从服务器端发送文件的长度)。

如果客户端和服务器是同一台机器,则此代码可以正常工作,但如果文件位于不同的计算机上,则该文件会失真。

4 个答案:

答案 0 :(得分:18)

在Java中复制流的规范方法:

int count;
byte[] buffer = new byte[8192];
while ((count = in.read(buffer)) > 0)
{
  out.write(buffer, 0, count);
}

适用于任何大于零的缓冲区大小。应尽量避免将缓冲区大小与输入大小联系起来的诱惑。

答案 1 :(得分:8)

我认为问题在于您忽略了各种read调用返回的值,并假设它们完全填满了缓冲区。这是有问题的:

  • 从文件中读取时, last 读取可能不会填充缓冲区。

  • 从套接字读取时,任何读取都可能在填充缓冲区之前返回。

您的写入会将垃圾放入流(服务器端)和目标文件(客户端)的最终结果。

此外,根据文件的大小将文件分成多个块是毫无意义的。只需阅读,直到你到达文件末尾。

答案 2 :(得分:6)

请勿重新发明轮子,请使用IOUtils.copy()

答案 3 :(得分:0)

请勿使用数据包 尝试使用ByteArrayOutputStream而不是使用静态字节数组 继续读取输入流,直到你达到EOF。 n将其中的每一个写入ByteArrayOutputStream。


InputStream is = sock.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int byteToBeRead = -1;
while((byteToBeRead = is.read())!=-1){
baos.write(byteToBeRead);
}
byte[] mybytearray = baos.toByteArray();
bos.write(mybytearray, 0,mybytearray.length);

希望这有帮助。