2017-04-17 66 views
0

我在下面发布的代码适用于套接字上的单个文件传输。但它不适用于套接字上的多个文件传输。当通过套接字尝试多个文件传输时,代码崩溃。如何通过byte []流读取多个文件的Socket InputStream?

我通过循环发送代码x次的服务器发送多个文件,并运行接收代码x次。当试图发送多个文件时,第一个文件将成功发送,第二个文件名和大小将被成功读取,但在此之后发生我代码中的错误。

在我的接收客户端,我尝试使用这里发布的建议:Java multiple file transfer over socket但没有成功。

错误在客户端。

我问的问题是:为什么不是这个代码适用于多个文件,我该如何解决它?

服务器发送

try{ 
    byte[] bytes = new byte[(int)file.length()]; 
    FileInputStream fis = new FileInputStream(file); 
    OutputStream os = socket.getOutputStream(); 

    out.println(file.getName()); // Send Filename 
    out.println(file.length()); // Send filesize 

    int count; 
    while ((count = fis.read(bytes)) > 0) { 
     os.write(bytes, 0, count); 
    } 
    os.flush(); 
    fis.close(); 
    }catch(IOException e){ 
    e.printStackTrace(); 
    } 
} 

客户Recieving

try{ 
    String file = in.readLine(); // Read filename 
    int fileSize = Integer.parseInt(in.readLine()); // Read Filesize 
    //ERROR HAPPENING ON LINE ABOVE IN LOOPS AFTER THE FIRST 
    byte [] buf = new byte [fileSize]; 
    FileOutputStream fos = new FileOutputStream(file); 
    InputStream is = socket.getInputStream(); 

    int count = 0; 
    while (fileSize > 0 && (count = is.read(buf, 0, (int)Math.min(buf.length, fileSize))) != -1){ 
    fos.write(buf, 0, count); 
    fileSize -= count; 
    } 

    fos.close(); 
}catch(IOException e){ 
    e.printStackTrace(); 
} 

该错误是一个NumberFormatException异常,在当客户端接收文件的一部分之后的第一个用于将输入到档案大小环路。

+0

当你说“在这之后我的代码错误发生”,还请添加错误在这里,所以我们不需要去猜测其中一百一些可能的错误之一是。 –

+0

你有异常追踪吗? – efekctive

+0

@ M.Prokhorov在我的文章的底部添加。 – tester

回答

1

在将原始字节直接写入PrintWriter所连接的OutputStream之前,请确保您的flushPrintWriter。否则,您可以将任何缓冲区数据按顺序写入底层套接字。

但更重要的是,确保如果您在接收端使用缓冲读取,即使用接收文件名和文件大小的相同缓冲区读取文件字节。您还应该使用较小的固定块传输File,不要为整个文件大小分配一个byte[]阵列,这对于大文件而言是浪费内存,并且可能会失败。

服务器:

try{ 
    byte[] bytes = new byte[1024]; 

    FileInputStream fis = new FileInputStream(file); 
    OutputStream os = socket.getOutputStream(); 
    BufferedOutputStream bos = new BufferedOutputStream(os); 

    PrinterWriter pw = new PrintWriter(bos); 
    pw.println(file.getName()); // Send Filename 
    pw.println(file.length()); // Send filesize 
    pw.flush(); 

    int count; 
    while ((count = fis.read(bytes)) > 0) { 
     bos.write(bytes, 0, count); 
    } 
    bos.flush(); 
    fis.close(); 
    }catch(IOException e){ 
    e.printStackTrace(); 
    } 
} 

客户:

try{ 
    byte [] buf = new byte [1024]; 

    FileOutputStream fos = new FileOutputStream(file); 
    InputStream is = socket.getInputStream(); 
    BufferedInputStream bis = new BufferedInputStream(is); 

    InputStreamReader isr = new InputStreamReader(bis); 
    String file = isr.readLine(); // Read filename 
    long fileSize = Long.parseLong(isr.readLine()); // Read Filesize 

    int count = 0; 
    while ((fileSize > 0) && (count = bis.read(buf, 0, (int)Math.min(buf.length, fileSize))) > 0){ 
    fos.write(buf, 0, count); 
    fileSize -= count; 
    } 

    fos.close(); 
}catch(IOException e){ 
    e.printStackTrace(); 
} 

话虽这么说,你也可以考虑使用DataOutputStream.writeLong()DataInputStream.readLong()发送/接收文件的大小在原来的二进制格式,而不是作为一个文本字符串:

服务器:

try{ 
    byte[] bytes = new byte[1024]; 

    FileInputStream fis = new FileInputStream(file); 
    OutputStream os = socket.getOutputStream(); 
    BufferedOutputStream bos = new BufferedOutputStream(os); 

    PrinterWriter pw = new PrintWriter(bos); 
    pw.println(file.getName()); // Send Filename 
    pw.flush(); 

    DataOutputStream dos = new DataOutputStream(bos); 
    dos.writeLong(file.length()); // Send filesize 
    dos.flush(); 

    int count; 
    while ((count = fis.read(bytes)) > 0) { 
     bos.write(bytes, 0, count); 
    } 
    bos.flush(); 
    fis.close(); 
    }catch(IOException e){ 
    e.printStackTrace(); 
    } 
} 

客户:

try{ 
    byte [] buf = new byte [1024]; 

    FileOutputStream fos = new FileOutputStream(file); 
    InputStream is = socket.getInputStream(); 
    BufferedInputStream bis = new BufferedInputStream(is); 

    InputStreamReader isr = new InputStreamReader(bis); 
    String file = isr.readLine(); // Read filename 

    DataInputStream dis = new DataInputStream(bos); 
    long fileSize = dis.readLong(); // Read Filesize 

    int count = 0; 
    while ((fileSize > 0) && (count = bis.read(buf, 0, (int)Math.min(buf.length, fileSize))) > 0){ 
    fos.write(buf, 0, count); 
    fileSize -= count; 
    } 

    fos.close(); 
}catch(IOException e){ 
    e.printStackTrace(); 
} 
+0

谢谢您回答我的问题,现在可以在给出的例子帮助下完美地工作。 – tester