2012-01-15 67 views
3

我有一个FileServer和一个FileClient,当客户端连接时,服务器发送一个文件。这是一个简单的程序,只是为了理解背后的概念。文件传输中的数据丢失 - JAVA?

我能够将文件从服务器发送到客户端,缓冲区为1024. 问题是接收的文件总是比原始文件小0.01 MB左右。因此,mp3文件会丢失一些信息,并且视频文件只是不玩。

我在服务器&客户端的while循环中放了一些prinln语句。我发现我的服务器没有发送整个文件。

//Server 
    byte [] mybytearray = new byte [1024];  
    FileInputStream fis = new FileInputStream(myFile); 
    BufferedInputStream bis = new BufferedInputStream(fis); 
    bis.read(mybytearray,0,mybytearray.length); 
    OutputStream os = sock.getOutputStream(); 
    System.out.println("Sending...\n mybytearray length:"+mybytearray.length+"file length:"+(int)myFile.length()); 
    int read, readTotal=0; 
    while ((read = fis.read(mybytearray,0,mybytearray.length)) != -1) { 

     os.write(mybytearray, 0, read); 
     System.out.println("File REad:"+read+"readtotal:"+readTotal); //* 
     readTotal += read; 
} 
    System.out.println("Final File Read:"+read+" Final readtotal:"+readTotal); 
    os.flush(); 
    sock.close(); 
    } 

的println语句,输出为:

Sending... 
mybytearray length:1024file length:12767554 
File REad:1024readtotal:0 
File REad:1024readtotal:1024 
.............and a lot of it...and then 
File REad:1024readtotal:12756992 
File REad:1024readtotal:12758016 
File REad:322readtotal:12759040 
Final File Read:-1 Final readtotal:12759362 

文件长度:12767554 &最后readTotal:12759362 shud是相等的。我不明白为什么最后读取的值较低[322],而它仍然可以有1024.

任何形式的帮助,我们将不胜感激。 谢谢。

[编辑]

//Client 
int read; 
int totalRead = 0; 

while ((read = is.read(mybytearray,0,mybytearray.length)) != -1) { 
     bos.write(mybytearray, 0 , read); 

     totalRead += read; 
     System.out.println("\nread:"+read+"\ntotalread: "+totalRead); 
} 
System.out.println("Final File Read:"+read+" Final readtotal:"+totalRead); 
bos.write(mybytearray, 0 , read); //57 Line in FileClient.java 
bos.flush(); 

我再次尝试发送一个文件。这次是一个txt。 这是我的服务器的输出

Sending... 
mybytearray length:1024file length:1232 
File REad:1024readtotal:0 
File REad:208readtotal:1024 
Final File Read:-1 Final readtotal:1232 

而这一次在客户端

read:208 
totalread: 1232 
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException 
    Final File Read:-1  Final readtotal:1232 

at java.lang.System.arraycopy(Native Method) 
at java.io.BufferedOutputStream.write(Unknown Source) 
at FileClient.main(FileClient.java:57) 

readtotal值是一样的,但有时我得到这个错误,有时候我不。

[BIG编辑 - 完整的客户端代码]

public class FileClient{ 
public static void main (String [] args) throws IOException { 

long start = System.currentTimeMillis(); 
int bytesRead; 
int current = 0; 
final JFrame f = new JFrame("Sample"); 
f.getContentPane().setLayout(new FlowLayout()); 
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
f.setSize(590,490); 
f.setVisible(true); 
// localhost for testing 
Socket sock = new Socket("localhost",13267); 
System.out.println("Connecting..."); 
File f1=new File(RecieveObject(sock)); 


// receive file 
byte [] mybytearray = new byte [1024]; 
InputStream is = sock.getInputStream(); 


FileOutputStream fos = new FileOutputStream(f1); 
ProgressMonitorInputStream nn= new ProgressMonitorInputStream(f,"reading",is); 
BufferedOutputStream bos = new BufferedOutputStream(fos); 
/* bytesRead = is.read(mybytearray,0,mybytearray.length); 
current = bytesRead; 


do { 
    bytesRead = 
     is.read(mybytearray, current, (mybytearray.length-current)); 
    System.out.println("mybytesarray length: "+mybytearray.length+"\ncurrent:"+current+"\nbytesread: "+bytesRead); 
    if(bytesRead >= 0) current += bytesRead; 
} while(bytesRead > -1); 

bos.write(mybytearray, 0 , current); 
bos.flush(); 
*/ 
int read; 
int totalRead = 0; 
//InputStream clientInputStream = clientSocket.getInputStream(); 
while ((read = is.read(mybytearray,0,mybytearray.length)) != -1) { 
     bos.write(mybytearray, 0 , read); 

     totalRead += read; 
     System.out.println("\nread:"+read+"\ntotalread: "+totalRead); 
} 
System.out.println("Final File Read:"+read+" Final readtotal:"+totalRead); 
// bos.write(mybytearray, 0 , read); 
bos.flush(); 
long end = System.currentTimeMillis(); 
System.out.println(end-start); 
bos.close(); 
sock.close(); 

} 
public static String RecieveObject(Socket s) { 
    String str = null; 
    try{ 
    ObjectInputStream is = new ObjectInputStream(s.getInputStream()); 



      str =(String)is.readUTF(); 


    } 
    catch(IOException ex){} 
    return str; 
} 

}

+0

我刚刚看到我发送的视频文件的大小是41046 KB,转换后它现在是41040 KB。我不知道6 KB已经在哪里? – Nikhar 2012-01-15 05:39:36

+0

删除客户端上的第57行后,我没有得到任何错误,但我仍然在传输后丢失6 KB的文件。 – Nikhar 2012-01-15 06:00:37

+0

如果您的原始问题已得到解答,您可能想从最后一次编辑中提出一个新问题。一个是具体的,并指出有问题的代码(57行是哪里?) – Bill 2012-01-15 06:05:50

回答

6

你缺少文件的开头(上升到第1024个字节),因您的5日线(包括评论)。您从输入中读取并将其提前,而不将其发送给客户端。删除此:

bis.read(mybytearray,0,mybytearray.length); 

此外,你不使用你的循环中BufferedInputStream。在这里使用bis.read而不是fis.read(如果您仍想要缓冲读取) - 或者一起删除BufferedInputStream

您的其他问题是您正在读取客户端上的最终字节,然后再次进入循环。再次调用is.read。由于套接字的另一端已关闭,所以它不会返回-1,而是抛出一个IOException。因此,bos.flush()和bos.close()不会被调用,并且您的最终字节永远不会写入磁盘。为了解决这个问题,请在关闭之前拨打sock.shutdownOutput。无论如何,你都会想在这个附近添加一些适当的异常处理。

+0

是的,我认为我错过了文件的开始部分,只是听了mp3文件rcvd。我会尝试.. – Nikhar 2012-01-15 04:58:26

+0

感谢您的大开眼界.. – Nikhar 2012-01-15 05:14:09

+0

@NikharSharma - 你的'readTotal'仍然显示差异?现在是否有可能由于客户端代码(可能是由于与此处类似的问题)而不是服务器代码导致丢失的字节?也许你可以发布客户端代码? – ziesemer 2012-01-15 05:39:37

1
byte [] mybytearray = new byte [1024];  
FileInputStream fis = new FileInputStream(myFile); 
BufferedInputStream bis = new BufferedInputStream(fis); 
OutputStream os = sock.getOutputStream(); 
System.out.println("Sending...\n mybytearray length:"+mybytearray.length+"filelength:"+(int)myFile.length()); 
int read, readTotal=0; 
while ((read = bis.read(mybytearray,0,mybytearray.length)) != -1) { 
    os.write(mybytearray, 0, read); 
    System.out.println("File REad:"+read+"readtotal:"+readTotal); //* 
    readTotal += read; 
} 
System.out.println("Final File Read:"+read+" Final readtotal:"+readTotal); 
os.flush(); 
sock.close(); 
} 
+0

谢谢...我明白了.. – Nikhar 2012-01-15 05:14:31