@Override
	public void startTransfer() throws TransferException {
		Runnable readRunner = new Runnable() {
			public void run() {
				try {
					logger.debug("Socket ready for read.. " + socket);
					logger.debug("Local port:"
							+ socket.getLocalSocketAddress().toString());

					// 初始化缓冲区和一些变量
					byte[] buff = new byte[1024];
					int len = 0;

					// 循环读取数据，直到遇到流的末尾，或者用户主动关闭连接
					// 注意这里不能在stopTransfer里只改变关闭标志而不关闭流，否则会在reader.read()方法阻塞掉，即是中断线程也没用
					// 线程在阻塞读取数据时是不能中断的，只能强制关闭流，阻塞的reader.read()方法就会立即抛出IO异常，就可以结束读线程
					while (true) {
						len = reader.read(buff, 0, buff.length);
						// 这里还需要判断是否读取到流的末尾，否则会进入死循环，通常返回-1表示流的结尾
						// 如果读取到结尾，表明是服务器主动关闭了连接，抛出这个异常，通知上层做资源清理工作
						if (len == -1) {
							logger.debug("Connection closed by server.."
									+ socket);
							raiseException(new TransferException(
									"Connection closed by server. " + socket));
							break;
						} else {
							bytesRecived(buff, 0, len);
						}
					}
				} catch (IOException e) {
					// 当发生IO异常时可能是网络出现问题，也可能是用户关闭了连接，这里需要判断下
					if (!userCloseFlag) {
						logger.warn("Connection error.. " + socket);
						raiseException(new TransferException(e));
					} else {
						logger.debug("Connection closed by user.." + socket);
					}
				}

				// 程序执行到这里，表明流已经读取完毕，可能是服务器主动关闭了连接，或者用户关闭了连接
				// 如果是服务器关闭了连接，这里就需要关闭流，如果是用户关闭了流，就什么也不做，因为在stopTranfer方法中就已经关闭了
				if (!userCloseFlag) {
					userCloseFlag = true;
					try {
						writer.close();
						reader.close();
					} catch (IOException e) {
						logger.warn("Close socket stream failed.. " + socket, e);
					}
				}
			}
		};

		readThread = new Thread(readRunner);
		readThread.setName(getTransferName());

		readThread.start();

	}