2011-08-05 81 views
0

我正在制作一个网络文件传输系统,用于通过java网络传输任何类型的文件。大小也可以是任何种类。因此我使用UTF-8协议来完成任务。通过Java中的Socket传输文件

我提供了我所做的代码,但问题是有些时候文件被转移,因为它是完全没有问题的。但是有时只有几kb的数据在接收端跳过,这实际上限制了mp3/video/image文件的正确打开。我认为问题在于BUFFER。我没有创建任何缓冲区,现在,我认为这可能对我有用。

我真的很感激,如果任何人都可以提供任何有关问题的帮助,以便文件得到充分传输。

客户端:--- >>文件发送方

Socket clientsocket = new Socket(host,6789);      // host contains the ip address of the remote server 
DataOutputStream outtoserver = new DataOutputStream(clientsocket.getOutputStream()); 
try 
{ 
    int r=0; 
    FileInputStream fromFile1 = new FileInputStream(path);     // "path" is the of the file being sent. 
    while(r!=-1) 
    { 
     r = fromFile1.read(); 
     outtoserver.writeUTF(r+""); 
    } 
} 
catch(Exception e) 
{ 
    System.out.println(e.toString()); 
} 
clientsocket.close(); 

服务器端:--- >>文件接收

ServerSocket welcome = new ServerSocket(6789); 
Socket conn = welcome.accept(); 
try 
{ 
    String r1 = new String(); 
    int r=0; 
    FileOutputStream toFile1 = new FileOutputStream(path);     // "path" is the of the file being received. 
    BufferedOutputStream toFile= new BufferedOutputStream(toFile1); 
    DataInputStream recv = new DataInputStream(conn.getInputStream()); 
    while(r!=-1) 
    { 
     r1 = recv.readUTF(); 
     r = Integer.parseInt(r1); 
     toFile.write(r); 
    } 
} 
catch(Exception e) 
{ 
    System.out.println(e.toString()); 
} 
+1

如果您使用的是文件,为什么还要编码?只需写入字节。 –

回答

5

我不明白你为什么将二进制数据编码为文本。

普通套接字可以发送和接收字节流没有任何问题。因此,只需使用FileInputStream将文件作为字节读取,然后将字节按原样写入套接字。 (对于记录,您正在做的事情可能是为输入文件的每个字节发送3到5个字节,而您正在读取输入文件的一个字节,而没有任何缓冲,这些错误和其他人做有可能对文件传输速度显著的影响。获得性能的方法是简单地使用至少1K字节的缓冲区大小,读取和写入字节数组。)


我不知道但是我怀疑你丢失了一些数据的原因是你在关闭发送端的套接字之前没有刷新或关闭outtoserver

跟进

我也注意到,您不冲水/在接收端关闭toFile,这可能会导致你在文件的结尾丢失数据。

+0

+1:它一定非常慢。 “文件发件人”也不使用任何缓冲。 –

+0

yopu可以用一些例子来详细说明这一点:“只需使用FileInputStream将文件作为字节读取,并将字节按原样写入套接字”。谢谢。 –

+0

结合http://docs.oracle.com/javase/tutorial/essential/io/bytestreams.html和http://docs.oracle提供的经验教训。COM/JavaSE的/教程/网络/插座/ readingWriting.html –

1

我看到的第一个问题是您使用的是DataInputStreamDataOutputStream。这些是用于读/写原始Java类型(int,long等),您不需要它们仅用于二进制数据。

另一个问题是,你不刷新你的文件输出流 - 这可能会导致丢失的字节。

0

显式刷新可能有助于这种情况。