Example usage for java.net Socket getRemoteSocketAddress

List of usage examples for java.net Socket getRemoteSocketAddress

Introduction

In this page you can find the example usage for java.net Socket getRemoteSocketAddress.

Prototype

public SocketAddress getRemoteSocketAddress() 

Source Link

Document

Returns the address of the endpoint this socket is connected to, or null if it is unconnected.

Usage

From source file:org.apache.hadoop.hdfs.server.datanode.CachingDataXceiver.java

private CachingDataXceiver(Socket s, SocketInputWrapper socketInput, DataNode datanode,
        CachingDataXceiverServer dataXceiverServer, BlockCache blockCache) throws IOException {

    super(new DataInputStream(new BufferedInputStream(socketInput, HdfsConstants.SMALL_BUFFER_SIZE)));

    this.s = s;/*from   w w w.  j a  v  a2  s. c  om*/
    this.socketInputWrapper = socketInput;
    this.isLocal = s.getInetAddress().equals(s.getLocalAddress());
    this.datanode = datanode;
    this.dnConf = datanode.getDnConf();
    this.dataXceiverServer = dataXceiverServer;
    this.blockCache = blockCache;
    remoteAddress = s.getRemoteSocketAddress().toString();
    localAddress = s.getLocalSocketAddress().toString();

    if (LOG.isDebugEnabled()) {
        LOG.debug("Number of active connections is: " + datanode.getXceiverCount());
    }
}

From source file:org.apache.hadoop.raid.BlockFixer.java

/**
 * Send a generated block to a datanode.
 * @param datanode Chosen datanode name in host:port form.
 * @param blockContents Stream with the block contents.
 * @param corruptBlock Block identifying the block to be sent.
 * @param blockSize size of the block./*from ww w . java2s .c o  m*/
 * @throws IOException
 */
private void sendFixedBlock(DatanodeInfo datanode, final InputStream blockContents, DataInputStream metadataIn,
        LocatedBlock block, long blockSize) throws IOException {
    InetSocketAddress target = NetUtils.createSocketAddr(datanode.name);
    Socket sock = SocketChannel.open().socket();

    int readTimeout = getConf().getInt(BLOCKFIX_READ_TIMEOUT, HdfsConstants.READ_TIMEOUT);
    NetUtils.connect(sock, target, readTimeout);
    sock.setSoTimeout(readTimeout);

    int writeTimeout = getConf().getInt(BLOCKFIX_WRITE_TIMEOUT, HdfsConstants.WRITE_TIMEOUT);

    OutputStream baseStream = NetUtils.getOutputStream(sock, writeTimeout);
    DataOutputStream out = new DataOutputStream(
            new BufferedOutputStream(baseStream, FSConstants.SMALL_BUFFER_SIZE));

    boolean corruptChecksumOk = false;
    boolean chunkOffsetOK = false;
    boolean verifyChecksum = true;
    boolean transferToAllowed = false;

    try {
        LOG.info("Sending block " + block.getBlock() + " from " + sock.getLocalSocketAddress().toString()
                + " to " + sock.getRemoteSocketAddress().toString() + " " + blockSize + " bytes");
        RaidBlockSender blockSender = new RaidBlockSender(block.getBlock(), blockSize, 0, blockSize,
                corruptChecksumOk, chunkOffsetOK, verifyChecksum, transferToAllowed, metadataIn,
                new RaidBlockSender.InputStreamFactory() {
                    @Override
                    public InputStream createStream(long offset) throws IOException {
                        // we are passing 0 as the offset above, so we can safely ignore
                        // the offset passed
                        return blockContents;
                    }
                });

        DatanodeInfo[] nodes = new DatanodeInfo[] { datanode };
        DataTransferProtocol.Sender.opWriteBlock(out, block.getBlock(), 1,
                DataTransferProtocol.BlockConstructionStage.PIPELINE_SETUP_CREATE, 0, blockSize, 0, "", null,
                nodes, block.getBlockToken());
        blockSender.sendBlock(out, baseStream);

        LOG.info("Sent block " + block.getBlock() + " to " + datanode.name);
    } finally {
        out.close();
    }
}

From source file:com.mirth.connect.connectors.tcp.TcpReceiver.java

@Override
public void onStart() throws ConnectorTaskException {
    disposing.set(false);//from   ww  w . j a  v  a  2 s  . c o m
    results.clear();
    clientReaders.clear();

    if (connectorProperties.isServerMode()) {
        // If we're in server mode, use the max connections property to initialize the thread pool
        executor = new ThreadPoolExecutor(0, maxConnections, 60L, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>());
    } else {
        // If we're in client mode, only a single thread is needed
        executor = Executors.newSingleThreadExecutor();
    }

    if (connectorProperties.isServerMode()) {
        try {
            createServerSocket();
        } catch (IOException e) {
            throw new ConnectorTaskException("Failed to create server socket (" + connectorProperties.getName()
                    + " \"Source\" on channel " + getChannelId() + ").", e);
        }
    }

    // Create the acceptor thread
    thread = new Thread(
            "TCP Receiver Server Acceptor Thread on " + getChannel().getName() + " (" + getChannelId() + ")") {
        @Override
        public void run() {
            while (getCurrentState() == DeployedState.STARTED) {
                Socket socket = null;

                if (connectorProperties.isServerMode()) {
                    // Server mode; wait to accept a client socket on the ServerSocket
                    try {
                        logger.debug("Waiting for new client socket (" + connectorProperties.getName()
                                + " \"Source\" on channel " + getChannelId() + ").");
                        socket = serverSocket.accept();
                        logger.trace("Accepted new socket: " + socket.getRemoteSocketAddress().toString()
                                + " -> " + socket.getLocalSocketAddress());
                    } catch (java.io.InterruptedIOException e) {
                        logger.debug("Interruption during server socket accept operation ("
                                + connectorProperties.getName() + " \"Source\" on channel " + getChannelId()
                                + ").", e);
                    } catch (Exception e) {
                        logger.debug("Error accepting new socket (" + connectorProperties.getName()
                                + " \"Source\" on channel " + getChannelId() + ").", e);
                    }
                } else {
                    // Client mode, manually initiate a client socket
                    try {
                        logger.debug("Initiating for new client socket (" + connectorProperties.getName()
                                + " \"Source\" on channel " + getChannelId() + ").");
                        if (connectorProperties.isOverrideLocalBinding()) {
                            socket = SocketUtil.createSocket(configuration, getLocalAddress(), getLocalPort());
                        } else {
                            socket = SocketUtil.createSocket(configuration);
                        }
                        clientSocket = socket;
                        SocketUtil.connectSocket(socket, getRemoteAddress(), getRemotePort(), timeout);
                    } catch (Exception e) {
                        logger.error("Error initiating new socket (" + connectorProperties.getName()
                                + " \"Source\" on channel " + getChannelId() + ").", e);
                        closeSocketQuietly(socket);
                        socket = null;
                        clientSocket = null;
                    }
                }

                try {
                    ThreadUtils.checkInterruptedStatus();

                    if (socket != null) {
                        synchronized (clientReaders) {
                            TcpReader reader = null;

                            try {
                                // Only allow worker threads to be submitted if we're not currently trying to stop the connector
                                if (disposing.get()) {
                                    return;
                                }
                                reader = new TcpReader(socket);
                                clientReaders.add(reader);
                                results.add(executor.submit(reader));
                            } catch (RejectedExecutionException | SocketException e) {
                                if (e instanceof RejectedExecutionException) {
                                    logger.debug("Executor rejected new task (" + connectorProperties.getName()
                                            + " \"Source\" on channel " + getChannelId() + ").", e);
                                } else {
                                    logger.debug("Error initializing socket (" + connectorProperties.getName()
                                            + " \"Source\" on channel " + getChannelId() + ").", e);
                                }
                                clientReaders.remove(reader);
                                closeSocketQuietly(socket);
                            }
                        }
                    }

                    if (connectorProperties.isServerMode()) {
                        // Remove any completed tasks from the list, but don't try to retrieve currently running tasks
                        cleanup(false, false, true);
                    } else {
                        // Wait until the TcpReader is done
                        cleanup(true, false, true);

                        String info = "Client socket finished, waiting "
                                + connectorProperties.getReconnectInterval() + " ms...";
                        eventController.dispatchEvent(new ConnectionStatusEvent(getChannelId(), getMetaDataId(),
                                getSourceName(), ConnectionStatusEventType.INFO, info));

                        // Use the reconnect interval to determine how long to wait until creating another socket
                        sleep(reconnectInterval);
                    }
                } catch (InterruptedException e) {
                    return;
                }
            }
        }
    };
    thread.start();
}

From source file:gridool.util.xfer.RecievedFileWriter.java

public final void handleRequest(@Nonnull final SocketChannel inChannel, @Nonnull final Socket socket)
        throws IOException {
    final StopWatch sw = new StopWatch();
    if (!inChannel.isBlocking()) {
        inChannel.configureBlocking(true);
    }//from w  ww.ja  v  a 2  s . c  om

    InputStream in = socket.getInputStream();
    DataInputStream dis = new DataInputStream(in);

    String fname = IOUtils.readString(dis);
    String dirPath = IOUtils.readString(dis);
    long len = dis.readLong();
    boolean append = dis.readBoolean();
    boolean ackRequired = dis.readBoolean();
    boolean hasAdditionalHeader = dis.readBoolean();
    if (hasAdditionalHeader) {
        readAdditionalHeader(dis, fname, dirPath, len, append, ackRequired);
    }

    final File file;
    if (dirPath == null) {
        file = new File(baseDir, fname);
    } else {
        File dir = FileUtils.resolvePath(baseDir, dirPath);
        file = new File(dir, fname);
    }

    preFileAppend(file, append);
    final FileOutputStream dst = new FileOutputStream(file, append);
    final String fp = file.getAbsolutePath();
    final ReadWriteLock filelock = accquireLock(fp, locks);
    final FileChannel fileCh = dst.getChannel();
    final long startPos = file.length();
    try {
        NIOUtils.transferFully(inChannel, 0, len, fileCh); // REVIEWME really an atomic operation?
    } finally {
        IOUtils.closeQuietly(fileCh, dst);
        releaseLock(fp, filelock, locks);
        postFileAppend(file, startPos, len);
    }
    if (ackRequired) {
        OutputStream out = socket.getOutputStream();
        DataOutputStream dos = new DataOutputStream(out);
        dos.writeLong(len);
        postAck(file, startPos, len);
    }

    if (LOG.isDebugEnabled()) {
        SocketAddress remoteAddr = socket.getRemoteSocketAddress();
        LOG.debug("Received a " + (append ? "part of file '" : "file '") + file.getAbsolutePath() + "' of "
                + len + " bytes from " + remoteAddr + " in " + sw.toString());
    }
}

From source file:xbird.util.xfer.RecievedFileWriter.java

public final void handleRequest(@Nonnull final SocketChannel inChannel, @Nonnull final Socket socket)
        throws IOException {
    final StopWatch sw = new StopWatch();
    if (!inChannel.isBlocking()) {
        inChannel.configureBlocking(true);
    }/*www.  j a v  a  2  s  .c om*/

    InputStream in = socket.getInputStream();
    DataInputStream dis = new DataInputStream(in);

    String fname = IOUtils.readString(dis);
    String dirPath = IOUtils.readString(dis);
    long len = dis.readLong();
    boolean append = dis.readBoolean();
    boolean ackRequired = dis.readBoolean();
    boolean hasAdditionalHeader = dis.readBoolean();
    if (hasAdditionalHeader) {
        readAdditionalHeader(dis, fname, dirPath, len, append, ackRequired);
    }

    final File file;
    if (dirPath == null) {
        file = new File(baseDir, fname);
    } else {
        File dir = FileUtils.resolvePath(baseDir, dirPath);
        file = new File(dir, fname);
    }

    preFileAppend(file, append);
    final FileOutputStream dst = new FileOutputStream(file, append);
    final String fp = file.getAbsolutePath();
    final ReadWriteLock filelock = accquireLock(fp, locks);
    final FileChannel fileCh = dst.getChannel();
    final long startPos = file.length();
    try {
        NIOUtils.transferFullyFrom(inChannel, 0, len, fileCh); // REVIEWME really an atomic operation?
    } finally {
        IOUtils.closeQuietly(fileCh, dst);
        releaseLock(fp, filelock, locks);
        postFileAppend(file, startPos, len);
    }
    if (ackRequired) {
        OutputStream out = socket.getOutputStream();
        DataOutputStream dos = new DataOutputStream(out);
        dos.writeLong(len);
        postAck(file, startPos, len);
    }

    if (LOG.isDebugEnabled()) {
        SocketAddress remoteAddr = socket.getRemoteSocketAddress();
        LOG.debug("Received a " + (append ? "part of file '" : "file '") + file.getAbsolutePath() + "' of "
                + len + " bytes from " + remoteAddr + " in " + sw.toString());
    }
}

From source file:org.apache.hadoop.hdfs.server.datanode.CachingDataXceiver.java

@Override
public void replaceBlock(final ExtendedBlock block, final Token<BlockTokenIdentifier> blockToken,
        final String delHint, final DatanodeInfo proxySource) throws IOException {
    updateCurrentThreadName("Replacing block " + block + " from " + delHint);

    /* read header */
    block.setNumBytes(dataXceiverServer.estimateBlockSize);
    if (datanode.isBlockTokenEnabled) {
        try {/*w w w  . ja  v a2s  .  c  o  m*/
            datanode.blockPoolTokenSecretManager.checkAccess(blockToken, null, block,
                    BlockTokenSecretManager.AccessMode.REPLACE);
        } catch (InvalidToken e) {
            LOG.warn("Invalid access token in request from " + remoteAddress
                    + " for OP_REPLACE_BLOCK for block " + block + " : " + e.getLocalizedMessage());
            sendResponse(s, ERROR_ACCESS_TOKEN, "Invalid access token", dnConf.socketWriteTimeout);
            return;
        }
    }

    if (!dataXceiverServer.balanceThrottler.acquire()) { // not able to start
        String msg = "Not able to receive block " + block.getBlockId() + " from " + s.getRemoteSocketAddress()
                + " because threads quota is exceeded.";
        LOG.warn(msg);
        sendResponse(s, ERROR, msg, dnConf.socketWriteTimeout);
        return;
    }

    Socket proxySock = null;
    DataOutputStream proxyOut = null;
    Status opStatus = SUCCESS;
    String errMsg = null;
    BlockReceiver blockReceiver = null;
    DataInputStream proxyReply = null;

    try {
        // get the output stream to the proxy
        InetSocketAddress proxyAddr = NetUtils.createSocketAddr(proxySource.getXferAddr());
        proxySock = datanode.newSocket();
        NetUtils.connect(proxySock, proxyAddr, dnConf.socketTimeout);
        proxySock.setSoTimeout(dnConf.socketTimeout);

        OutputStream baseStream = NetUtils.getOutputStream(proxySock, dnConf.socketWriteTimeout);
        proxyOut = new DataOutputStream(new BufferedOutputStream(baseStream, HdfsConstants.SMALL_BUFFER_SIZE));

        /* send request to the proxy */
        new Sender(proxyOut).copyBlock(block, blockToken);

        // receive the response from the proxy
        proxyReply = new DataInputStream(
                new BufferedInputStream(NetUtils.getInputStream(proxySock), HdfsConstants.IO_FILE_BUFFER_SIZE));
        BlockOpResponseProto copyResponse = BlockOpResponseProto
                .parseFrom(HdfsProtoUtil.vintPrefixed(proxyReply));

        if (copyResponse.getStatus() != SUCCESS) {
            if (copyResponse.getStatus() == ERROR_ACCESS_TOKEN) {
                throw new IOException("Copy block " + block + " from " + proxySock.getRemoteSocketAddress()
                        + " failed due to access token error");
            }
            throw new IOException(
                    "Copy block " + block + " from " + proxySock.getRemoteSocketAddress() + " failed");
        }

        // get checksum info about the block we're copying
        ReadOpChecksumInfoProto checksumInfo = copyResponse.getReadOpChecksumInfo();
        DataChecksum remoteChecksum = DataTransferProtoUtil.fromProto(checksumInfo.getChecksum());
        // open a block receiver and check if the block does not exist
        blockReceiver = new BlockReceiver(block, proxyReply, proxySock.getRemoteSocketAddress().toString(),
                proxySock.getLocalSocketAddress().toString(), null, 0, 0, 0, "", null, datanode,
                remoteChecksum);

        // receive a block
        blockReceiver.receiveBlock(null, null, null, null, dataXceiverServer.balanceThrottler, null);

        // notify name node
        datanode.notifyNamenodeReceivedBlock(block, delHint);

        LOG.info("Moved block " + block + " from " + s.getRemoteSocketAddress());

    } catch (IOException ioe) {
        opStatus = ERROR;
        errMsg = "opReplaceBlock " + block + " received exception " + ioe;
        LOG.info(errMsg);
        throw ioe;
    } finally {
        // receive the last byte that indicates the proxy released its thread resource
        if (opStatus == SUCCESS) {
            try {
                proxyReply.readChar();
            } catch (IOException ignored) {
            }
        }

        // now release the thread resource
        dataXceiverServer.balanceThrottler.release();

        // send response back
        try {
            sendResponse(s, opStatus, errMsg, dnConf.socketWriteTimeout);
        } catch (IOException ioe) {
            LOG.warn("Error writing reply back to " + s.getRemoteSocketAddress());
        }
        IOUtils.closeStream(proxyOut);
        IOUtils.closeStream(blockReceiver);
        IOUtils.closeStream(proxyReply);
    }

    // update metrics
    datanode.metrics.addReplaceBlockOp(elapsed());
}

From source file:org.apache.hadoop.hdfs.server.datanode.DataXceiver.java

/**
 * Receive a block and write it to disk, it then notifies the namenode to
 * remove the copy from the source./*from   ww  w  . jav  a2 s  .  com*/
 * 
 * @param in The stream to read from
 * @throws IOException
 */
private void replaceBlock(DataInputStream in) throws IOException {
    /* read header */
    long blockId = in.readLong();
    Block block = new Block(blockId, dataXceiverServer.estimateBlockSize, in.readLong()); // block id & generation stamp
    String sourceID = Text.readString(in); // read del hint
    DatanodeInfo proxySource = new DatanodeInfo(); // read proxy source
    proxySource.readFields(in);
    Token<BlockTokenIdentifier> accessToken = new Token<BlockTokenIdentifier>();
    accessToken.readFields(in);
    if (datanode.isBlockTokenEnabled) {
        try {
            datanode.blockTokenSecretManager.checkAccess(accessToken, null, block,
                    BlockTokenSecretManager.AccessMode.REPLACE);
        } catch (InvalidToken e) {
            LOG.warn("Invalid access token in request from " + remoteAddress
                    + " for OP_REPLACE_BLOCK for block " + block);
            sendResponse(s, (short) DataTransferProtocol.OP_STATUS_ERROR_ACCESS_TOKEN,
                    datanode.socketWriteTimeout);
            return;
        }
    }

    if (!dataXceiverServer.balanceThrottler.acquire()) { // not able to start
        LOG.warn("Not able to receive block " + blockId + " from " + s.getRemoteSocketAddress()
                + " because threads quota is exceeded.");
        sendResponse(s, (short) DataTransferProtocol.OP_STATUS_ERROR, datanode.socketWriteTimeout);
        return;
    }

    Socket proxySock = null;
    DataOutputStream proxyOut = null;
    short opStatus = DataTransferProtocol.OP_STATUS_SUCCESS;
    BlockReceiver blockReceiver = null;
    DataInputStream proxyReply = null;

    try {
        // get the output stream to the proxy
        InetSocketAddress proxyAddr = NetUtils.createSocketAddr(proxySource.getName());
        proxySock = datanode.newSocket();
        NetUtils.connect(proxySock, proxyAddr, datanode.socketTimeout);
        proxySock.setSoTimeout(datanode.socketTimeout);

        OutputStream baseStream = NetUtils.getOutputStream(proxySock, datanode.socketWriteTimeout);
        proxyOut = new DataOutputStream(new BufferedOutputStream(baseStream, SMALL_BUFFER_SIZE));

        /* send request to the proxy */
        proxyOut.writeShort(DataTransferProtocol.DATA_TRANSFER_VERSION); // transfer version
        proxyOut.writeByte(DataTransferProtocol.OP_COPY_BLOCK); // op code
        proxyOut.writeLong(block.getBlockId()); // block id
        proxyOut.writeLong(block.getGenerationStamp()); // block id
        accessToken.write(proxyOut);
        proxyOut.flush();

        // receive the response from the proxy
        proxyReply = new DataInputStream(
                new BufferedInputStream(NetUtils.getInputStream(proxySock), BUFFER_SIZE));
        short status = proxyReply.readShort();
        if (status != DataTransferProtocol.OP_STATUS_SUCCESS) {
            if (status == DataTransferProtocol.OP_STATUS_ERROR_ACCESS_TOKEN) {
                throw new IOException("Copy block " + block + " from " + proxySock.getRemoteSocketAddress()
                        + " failed due to access token error");
            }
            throw new IOException(
                    "Copy block " + block + " from " + proxySock.getRemoteSocketAddress() + " failed");
        }
        // open a block receiver and check if the block does not exist
        blockReceiver = new BlockReceiver(block, proxyReply, proxySock.getRemoteSocketAddress().toString(),
                proxySock.getLocalSocketAddress().toString(), false, "", null, datanode);

        // receive a block
        blockReceiver.receiveBlock(null, null, null, null, dataXceiverServer.balanceThrottler, -1);

        // notify name node
        datanode.notifyNamenodeReceivedBlock(block, sourceID);

        LOG.info("Moved block " + block + " from " + s.getRemoteSocketAddress());

    } catch (IOException ioe) {
        opStatus = DataTransferProtocol.OP_STATUS_ERROR;
        throw ioe;
    } finally {
        // receive the last byte that indicates the proxy released its thread resource
        if (opStatus == DataTransferProtocol.OP_STATUS_SUCCESS) {
            try {
                proxyReply.readChar();
            } catch (IOException ignored) {
            }
        }

        // now release the thread resource
        dataXceiverServer.balanceThrottler.release();

        // send response back
        try {
            sendResponse(s, opStatus, datanode.socketWriteTimeout);
        } catch (IOException ioe) {
            LOG.warn("Error writing reply back to " + s.getRemoteSocketAddress());
        }
        IOUtils.closeStream(proxyOut);
        IOUtils.closeStream(blockReceiver);
        IOUtils.closeStream(proxyReply);
    }
}

From source file:org.apache.hadoop.hdfs.server.datanode.DWRRDataXceiver.java

@Override
public void replaceBlock(final ExtendedBlock block, final Token<BlockTokenIdentifier> blockToken,
        final String delHint, final DatanodeInfo proxySource) throws IOException {
    updateCurrentThreadName("Replacing block " + block + " from " + delHint);

    /* read header */
    block.setNumBytes(DataXceiverServer.estimateBlockSize);
    if (datanode.isBlockTokenEnabled) {
        try {/*from w w w. j av a  2s.c o  m*/
            datanode.blockPoolTokenSecretManager.checkAccess(blockToken, null, block,
                    BlockTokenSecretManager.AccessMode.REPLACE);
        } catch (InvalidToken e) {
            LOG.warn("Invalid access token in request from " + remoteAddress
                    + " for OP_REPLACE_BLOCK for block " + block + " : " + e.getLocalizedMessage());
            sendResponse(ERROR_ACCESS_TOKEN, "Invalid access token");
            return;
        }
    }

    if (!DataXceiverServer.balanceThrottler.acquire()) { // not able to start
        String msg = "Not able to receive block " + block.getBlockId() + " from "
                + peer.getRemoteAddressString() + " because threads " + "quota is exceeded.";
        LOG.warn(msg);
        sendResponse(ERROR, msg);
        return;
    }

    Socket proxySock = null;
    DataOutputStream proxyOut = null;
    Status opStatus = SUCCESS;
    String errMsg = null;
    BlockReceiver blockReceiver = null;
    DataInputStream proxyReply = null;

    try {
        // get the output stream to the proxy
        final String dnAddr = proxySource.getXferAddr(connectToDnViaHostname);
        if (LOG.isDebugEnabled()) {
            LOG.debug("Connecting to datanode " + dnAddr);
        }
        InetSocketAddress proxyAddr = NetUtils.createSocketAddr(dnAddr);
        proxySock = datanode.newSocket();
        NetUtils.connect(proxySock, proxyAddr, dnConf.socketTimeout);
        proxySock.setSoTimeout(dnConf.socketTimeout);

        OutputStream unbufProxyOut = NetUtils.getOutputStream(proxySock, dnConf.socketWriteTimeout);
        InputStream unbufProxyIn = NetUtils.getInputStream(proxySock);
        if (dnConf.encryptDataTransfer
                && !dnConf.trustedChannelResolver.isTrusted(proxySock.getInetAddress())) {
            IOStreamPair encryptedStreams = DataTransferEncryptor.getEncryptedStreams(unbufProxyOut,
                    unbufProxyIn,
                    datanode.blockPoolTokenSecretManager.generateDataEncryptionKey(block.getBlockPoolId()));
            unbufProxyOut = encryptedStreams.out;
            unbufProxyIn = encryptedStreams.in;
        }

        proxyOut = new DataOutputStream(
                new BufferedOutputStream(unbufProxyOut, HdfsConstants.SMALL_BUFFER_SIZE));
        proxyReply = new DataInputStream(
                new BufferedInputStream(unbufProxyIn, HdfsConstants.IO_FILE_BUFFER_SIZE));

        /* send request to the proxy */
        new Sender(proxyOut).copyBlock(block, blockToken);

        // receive the response from the proxy

        BlockOpResponseProto copyResponse = BlockOpResponseProto.parseFrom(PBHelper.vintPrefixed(proxyReply));

        if (copyResponse.getStatus() != SUCCESS) {
            if (copyResponse.getStatus() == ERROR_ACCESS_TOKEN) {
                throw new IOException("Copy block " + block + " from " + proxySock.getRemoteSocketAddress()
                        + " failed due to access token error");
            }
            throw new IOException(
                    "Copy block " + block + " from " + proxySock.getRemoteSocketAddress() + " failed");
        }

        // get checksum info about the block we're copying
        ReadOpChecksumInfoProto checksumInfo = copyResponse.getReadOpChecksumInfo();
        DataChecksum remoteChecksum = DataTransferProtoUtil.fromProto(checksumInfo.getChecksum());
        // open a block receiver and check if the block does not exist
        blockReceiver = new BlockReceiver(block, proxyReply, proxySock.getRemoteSocketAddress().toString(),
                proxySock.getLocalSocketAddress().toString(), null, 0, 0, 0, "", null, datanode, remoteChecksum,
                CachingStrategy.newDropBehind());

        // receive a block
        blockReceiver.receiveBlock(null, null, null, null, DataXceiverServer.balanceThrottler, null);

        // notify name node
        datanode.notifyNamenodeReceivedBlock(block, delHint, blockReceiver.getStorageUuid());

        LOG.info("Moved " + block + " from " + peer.getRemoteAddressString() + ", delHint=" + delHint);

    } catch (IOException ioe) {
        opStatus = ERROR;
        errMsg = "opReplaceBlock " + block + " received exception " + ioe;
        LOG.info(errMsg);
        throw ioe;
    } finally {
        // receive the last byte that indicates the proxy released its thread resource
        if (opStatus == SUCCESS) {
            try {
                proxyReply.readChar();
            } catch (IOException ignored) {
            }
        }

        // now release the thread resource
        DataXceiverServer.balanceThrottler.release();

        // send response back
        try {
            sendResponse(opStatus, errMsg);
        } catch (IOException ioe) {
            LOG.warn("Error writing reply back to " + peer.getRemoteAddressString());
        }
        IOUtils.closeStream(proxyOut);
        IOUtils.closeStream(blockReceiver);
        IOUtils.closeStream(proxyReply);
    }

    //update metrics
    datanode.metrics.addReplaceBlockOp(elapsed());
}