Package freenet.io.xfer

Source Code of freenet.io.xfer.BulkReceiver

/* This code is part of Freenet. It is distributed under the GNU General
* Public License, version 2 (or at your option any later version). See
* http://www.gnu.org/ for further details of the GPL. */
package freenet.io.xfer;

import static java.util.concurrent.TimeUnit.SECONDS;

import freenet.io.comm.ByteCounter;
import freenet.io.comm.DMT;
import freenet.io.comm.DisconnectedException;
import freenet.io.comm.Message;
import freenet.io.comm.MessageFilter;
import freenet.io.comm.NotConnectedException;
import freenet.io.comm.PeerContext;
import freenet.io.comm.RetrievalException;
import freenet.support.ShortBuffer;

/**
* Bulk (not block) data transfer - receiver class. Bulk transfer is designed for largish files, much
* larger than blocks, where we have the whole file at the outset.
* @author toad
*/
public class BulkReceiver {

  static final long TIMEOUT = SECONDS.toMillis(60);
  /** Tracks the data we have received */
  final PartiallyReceivedBulk prb;
  /** Peer we are receiving from */
  final PeerContext peer;
  /** Transfer UID for messages */
  final long uid;
  private boolean sentCancel;
  /** Not persistent over reboots */
  final long peerBootID;
  private final ByteCounter ctr;

  public BulkReceiver(PartiallyReceivedBulk prb, PeerContext peer, long uid, ByteCounter ctr) {
    this.prb = prb;
    this.peer = peer;
    this.uid = uid;
    this.peerBootID = peer.getBootID();
    this.ctr = ctr;
   
    prb.recv = this;
  }

  public void onAborted() {
    synchronized(this) {
      if(sentCancel) return;
      sentCancel = true;
    }
    try {
      peer.sendAsync(DMT.createFNPBulkReceiveAborted(uid), null, ctr);
    } catch (NotConnectedException e) {
      // Cool
    }
  }

  /**
   * Receive the file.
   * @return True if the whole file was received, false otherwise.
   */
  public boolean receive() {
    while(true) {
      MessageFilter mfSendKilled = MessageFilter.create().setSource(peer).setType(DMT.FNPBulkSendAborted) .setField(DMT.UID, uid).setTimeout(TIMEOUT);
      MessageFilter mfPacket = MessageFilter.create().setSource(peer).setType(DMT.FNPBulkPacketSend) .setField(DMT.UID, uid).setTimeout(TIMEOUT);
      if(prb.hasWholeFile()) {
        try {
          peer.sendAsync(DMT.createFNPBulkReceivedAll(uid), null, ctr);
        } catch (NotConnectedException e) {
          // Ignore, we have the data.
        }
        return true;
      }
      Message m;
      try {
        m = prb.usm.waitFor(mfSendKilled.or(mfPacket), ctr);
      } catch (DisconnectedException e) {
        prb.abort(RetrievalException.SENDER_DISCONNECTED, "Sender disconnected");
        return false;
      }
      if(peer.getBootID() != peerBootID) {
        prb.abort(RetrievalException.SENDER_DIED, "Sender restarted");
        return false;
      }
      if(m == null) {
        prb.abort(RetrievalException.TIMED_OUT, "Sender timeout");
        return false;
      }
      if(m.getSpec() == DMT.FNPBulkSendAborted) {
        prb.abort(RetrievalException.SENDER_DIED, "Sender cancelled send");
        return false;
      }
      if(m.getSpec() == DMT.FNPBulkPacketSend) {
        int packetNo = m.getInt(DMT.PACKET_NO);
        byte[] data = ((ShortBuffer) m.getObject(DMT.DATA)).getData();
        prb.received(packetNo, data, 0, data.length);
      }
    }
  }
}
TOP

Related Classes of freenet.io.xfer.BulkReceiver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.