public void fileDescriptorReceived(DownloadConnection source, FileDescriptor fd) throws IOException { if (this.fd != null) { if (T.t) { T.info("Already has FD. Ignore the new one and start download for this connection."); } if (T.t) { T.ass(source.readyToStartDownload(), "Not ready to start download?"); } if (needsMoreDownloadConnections()) { source.startDownloadingBlock(); } return; } if (T.t) { T.debug("Received file descriptor " + fd); } this.fd = fd; setState(State.DOWNLOADING); ArrayList<DownloadConnection> al = new ArrayList<DownloadConnection>(); for (DownloadConnection c : connections.values()) { al.add(c); } for (DownloadConnection c : al) { if (c.readyToStartDownload() && needsMoreDownloadConnections()) { c.startDownloadingBlock(); } } }
protected void sendCommand(Command cmd) throws IOException { if (T.t) { T.debug("Sending command: " + cmd); } Packet p = netMan.createPacketForSend(); p.writeByte(cmd.value()); send(p); }
public int selectBestBlockForDownload(Friend remoteFriend) throws IOException { if (T.t) { T.debug("Selecting best block for download. Remote: " + remoteFriend); } BlockMask bm = blockMasks.get(remoteFriend.getGuid()); if (bm == null) { if (T.t) { T.info("Ehh. Don't know anything about this friends block mask. Can't download."); } return -1; } BitSet interestingBlocks = getInterestingBlocks(bm); // remove bocks in progress from interesting blocks: BlockFile bf = storage.getBlockFile(root); BitSet blocksInProgress = bf == null ? new BitSet() : bf.getBlocksInProgress(); blocksInProgress.flip(0, fd.getNumberOfBlocks()); blocksInProgress.and(interestingBlocks); if (blocksInProgress.cardinality() > 0) { // there are blocks of interest that are NOT in progress. Take one of these interestingBlocks = blocksInProgress; } // else there are only blocks in progress. Use any of them int highestBlockNumber = 0; if (bf != null) { highestBlockNumber = bf.getHighestCompleteBlock(); } highestBlockNumber += manager.getCore().getSettings().getInternal().getMaxfileexpandinblocks(); // we prefer to load blocks below highestBlockNumber if (interestingBlocks.nextSetBit(0) < highestBlockNumber) { // we're good - there are interesting blocks below the highest block number. // remove all blocks above highest block number: if (highestBlockNumber + 1 < fd.getNumberOfBlocks()) { interestingBlocks.clear(highestBlockNumber + 1, fd.getNumberOfBlocks()); } } // select a random block of the ones we're interested in - change this to rarest first in the // future int c = interestingBlocks.cardinality(); int n = (int) (Math.random() * c); for (int i = interestingBlocks.nextSetBit(0), j = 0; i >= 0; i = interestingBlocks.nextSetBit(i + 1), j++) { if (j == n) { return i; } } if (T.t) { T.trace("Can't find any block to download from " + remoteFriend); } return -1; }
public void send(int dstGuid, RPC rpc) throws IOException { if (dstGuid != getRemoteUserGUID()) { if (T.t) { T.debug("Rerouting package " + rpc + " to " + dstGuid); } route(dstGuid, rpc); } else { if (!rpc.isInitialized()) { rpc.init( this); // under certain conditions a rpc can be reused and sent a second time - then // it's the first init call that counts. Don't make it twice. } Packet p = createRPCPacket(rpc); if (T.t) { T.debug("--> Sending " + rpc + " (" + p.getPos() + " bytes) to " + getRemoteFriend()); } send(p); } }
public void received(int fromGuid, int hops, Packet packet, RPC outerRPC) throws IOException { int id = packet.readByte(); RPC rpc = RPCFactory.newInstance(id); if (rpc == null) { if (T.t) { T.warn("Skipping unknown RPC ID: " + id + "!!!"); } packet.skip(packet.getAvailable()); // skip contents of packet return; } else { if (T.t) { if (outerRPC == null) { T.debug( "<-- Recived " + rpc + " (" + (packet.getAvailable() + 1) + " bytes) from " + netMan.getFriendManager().getNode(fromGuid) + " (con: " + getRemoteFriend() + ")"); // +1 because we read one byte above } else { T.debug( "<----- Recived " + rpc + " (" + (packet.getAvailable() + 1) + " bytes) from " + netMan.getFriendManager().getNode(fromGuid) + " (con: " + getRemoteFriend() + ", outer: " + outerRPC + ")"); // +1 because we read one byte above } } rpc.init(this, fromGuid, hops); rpc.execute(packet); signalReceived(rpc); } }
public void blockMaskReceived(int srcGuid, int hops, BlockMask bm) { if (hops > 0) { if (T.t) { T.debug("Ignoring block mask coming from " + hops + " hops away."); } return; } if (!isInterestedInBlockMasks()) { if (T.t) { T.info("No longer interested in block masks for this download - ignore"); } return; } if (T.t) { T.debug("Received blockmask from " + srcGuid + ": " + bm + " size: " + bm.length()); } blockMasks.put(srcGuid, bm); if (state == State.WAITING_TO_START) { return; } if (connections.size() == 0) { try { if (T.t) { T.info("Got first block mask - starting download."); } openDownloadConnection(srcGuid); } catch (IOException e) { if (T.t) { T.warn("Could not connect to " + srcGuid + ". Waiting for next block mask: " + e); } } } else { if (getConnectionByGUID(srcGuid) == null) { try { if (fd != null && getInterestingBlocks(bm).isEmpty()) { if (T.t) { T.debug("Remote has blocks of file, but no that I'm interested of: " + srcGuid); } } else { if (connections.size() < manager.getMaxConnectionsPerDownload()) { if (T.t) { T.debug("Opening dl connection to another friend"); } openDownloadConnection(srcGuid); } else { if (T.t) { T.trace( "Not opening more connection for download " + this + ". have already: " + connections.size()); } } } } catch (IOException e) { if (T.t) { T.warn("Could not connect to " + srcGuid + ". Waiting for next block mask: " + e); } } } else { if (T.t) { T.info( "Already connected to " + srcGuid + " - no need to open another download connection"); } } } }