2011-12-15 162 views
1

我想用DatagramSocket发送一堆文件。但有一个我无法弄清楚的问题。传输图像文件以外的文件进行得很顺利,但在发送图像文件时,虽然服务器发送文件,但客户端仍然在接收时卡住。这是我的客户端和服务器端代码块:DatagramSocket:文件发送,客户端没有收到图像文件

服务器:

while (true) { 
     System.out.print("DatagramSocket: Waiting for file request...\n"); 
     buf = new byte[Integer.SIZE]; 
     packet = new DatagramPacket(buf, buf.length); 
     datagramSocket.receive(packet); 
     bb = ByteBuffer.wrap(buf); 

     // Receive request 
     buf = new byte[bb.getInt()]; 
     packet = new DatagramPacket(buf, buf.length); 
     datagramSocket.receive(packet); 

     System.out.print("DatagramSocket: File request received.\n"); 
     System.out.print("DatagramSocket: Requested file: "+new String(buf)+"\n"); 

     // Check file if it is exist. 
     File file = new File("kaynak/"+new String(buf)); 

     if (!file.exists()) { 
      System.out.print("DatagramSocket: File not found!\n"); 
      return; 
     } 

     // Send file length. 
     System.out.printf("DatagramSocket: Sending file length: %d\n", file.length()); 
     bb = ByteBuffer.allocate(Integer.SIZE).putInt((int) file.length()); 
     buf = bb.array(); 
     packet.setData(buf); 
     packet.setLength(buf.length); 
     datagramSocket.send(packet); 

     // Send file's relative path. 
     String relativePath = file.getAbsolutePath().substring(System.getProperty("user.dir").length() + 1); 
     System.out.printf("DatagramSocket: Sending file relative path: %s\n", relativePath); 
     bb.putInt(relativePath.getBytes().length); 
     datagramSocket.send(packet); 
     packet.setData(relativePath.getBytes()); 
     packet.setLength(relativePath.getBytes().length); 
     datagramSocket.send(packet); 

     // Save file to byte array. 
     bis = new BufferedInputStream(new FileInputStream(file)); 
     fileByteArray = new byte[(int) file.length()]; 
     bis.read(fileByteArray); 

     System.out.printf("DatagramSocket: Sending file.\n"); 
     int r = (int) file.length(); 
     int c = 0; 

     // Send file. 
     for (int i = 0; i < file.length(); i++) { 
      c = r < 512 ? r : 512; 
      packet.setData(ByteBuffer.wrap(fileByteArray, i, c).array()); 
      packet.setLength(c); 
      datagramSocket.send(packet); 
      r -= 512; 
      i += 511; 
     } 
     System.out.printf("DatagramSocket: File send.\n\n"); 
    } 

客户:

// Send file request. 
bb = ByteBuffer.allocate(Integer.SIZE).putInt(files.get(i).getBytes().length); 
message = bb.array(); 
packet = new DatagramPacket(message, message.length, InetAddress.getByName(host), dport); 
datagramSocket.send(packet); 
message = files.get(i).getBytes(); 
System.out.print("Requesting: "+new String(message)+"\n"); 
packet.setData(message); 
packet.setLength(message.length); 
datagramSocket.send(packet); 

// Receive file size. 
System.out.print("Requesting file length.\n"); 
message = ByteBuffer.allocate(Integer.SIZE).array(); 
packet.setData(message); 
packet.setLength(Integer.SIZE); 
datagramSocket.receive(packet); 
bb = ByteBuffer.wrap(message); 
int arraySize = bb.getInt(); 
System.out.printf("File size = %d baytes.\n", arraySize); 
fileByteArray = new byte[arraySize]; 

// Receive file's relative path. 
System.out.print("Requesting file's relative path.\n"); 
datagramSocket.receive(packet); 
message = ByteBuffer.allocate(message.length).array(); 
packet.setLength(message.length); 
datagramSocket.receive(packet); 
String htmlPath = new String(packet.getData()); 
System.out.printf("File's relative path = %s.\n", htmlPath); 
File file = new File("hedef/"+htmlPath.substring("kaynak".length())); 
file.getParentFile().mkdirs(); 
file.createNewFile(); 

// Receive file content. 
System.out.print("Requesting file content.\n"); 
int r = arraySize; 
int c = 0; 

for (int j = 0; j < arraySize; j++) { 
    c = r < 512 ? r : 512; 
    packet.setData(ByteBuffer.wrap(fileByteArray, j, c).array()); 
    packet.setLength(c); 
    datagramSocket.receive(packet); 
    r -= 512; 
    j += 511; 
} 

// Save file. 
System.out.print("Saving file.\n"); 
bos = new BufferedOutputStream(new FileOutputStream(file)); 
bos.write(fileByteArray); 
bos.flush(); 
System.out.print("File saved.\n\n"); 

我也很感激,如果可以给我提示一下我的代码,性能或错误使用提示。
在此先感谢。

更新:

将在for循环,它发送文件本身一点睡眠时间后,现在我能完成发送文件,但所有图像文件我已损坏。

for (int j = 0; j < arraySize; j++) { 
    c = r < 512 ? r : 512; 
    packet.setData(ByteBuffer.wrap(fileByteArray, j, c).array()); 
    packet.setLength(c); 
    datagramSocket.receive(packet); 
    r -= 512; 
    j += 511; 
    Thread.sleep(50); 
} 
+0

你为什么使用数据报发送文件?数据报并不总是可靠的,并且不能保证对方能够正确地获取数据。 – belgther 2011-12-15 10:05:05

+0

这是一个功课,我不得不使用数据报:) 我知道这是不可靠的。 – 2011-12-15 10:11:58

回答

2

从DatagramSocket文档:此方法阻塞,直到收到数据报。 很明显,有包丢失。

另外:最好不要分配数组来接收孔数据。想想一些4GB的视频文件......取而代之的是分配一个缓冲区数组(512),并在DatagramSocket.receive()之后立即将它写入BufferedOutputStream。

相关问题