2011-12-15 7 views
1

DatagramSocketを使用してたくさんのファイルを送信しようとしています。しかし、私が理解できない問題があります。イメージファイル以外のファイルを転送するとうまくいくが、イメージファイルを送信している間に、Serverはファイルを送信するが、受信にはまってしまう。ここに私のクライアント側とサーバー側のコードブロックです: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 (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

+0

それは宿題です、私はデータグラムを使用する必要があります:) 私はそれが信頼できないことを知っています。 –

+0

イメージを正常に送信できましたか?はいの場合、私は助けが必要です、あなたはそれをやっていますか? –

答えて

2

From From DatagramSocket documentation:このメソッドは、データグラムが受信されるまでブロックします。明らかに紛失しているパッケージがあります。

また、受信するホールデータを配列に割り当てない方がよいでしょう。いくつかの4GBのビデオファイルを考えてみてください...代わりに、あなたのread(512)のサイズのバッファ配列を割り当て、DatagramSocket.receive()の直後にBufferedOutputStreamに書き込みます。

+0

メモリ割り当てのヒントありがとうございます。 –

関連する問題