博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bt分析之bt种子发布---做种(2)
阅读量:5897 次
发布时间:2019-06-19

本文共 5352 字,大约阅读时间需要 17 分钟。

hot3.png

先来一张图:

在此之前,了解下

1.解析种子,放到SharedTorrent对象中

/**1.解析torrent文件到SharedTorrent对象中,并分片段*/			BtClient_ShareTorrent=SharedTorrent.fromFile(					new File(torrentPath),					new File(sourceFileParentPath));

 

        /**发布种子文件	 * @param torrentPath 	         torrent文件存放位置	 * @param sourceFileParentPath   共享文件的父路径,如:/share1/share2/file.pdf 	 *                                  则取/share1/share2  	 * @return  Client	 * */public Client shareTorrentFile(String torrentPath, String sourceFileParentPath) {		//注:这里sourceFileParentPath 如果是自己做种时,这个路径一定得是源文件所在的目录		//如果是添加torrentFile而下载时,为下载文件目录		this.saveDownloadPath=sourceFileParentPath;		this.torrentPath=torrentPath;				try {			/**1.解析torrent文件到SharedTorrent对象中,并分片段*/			BtClient_ShareTorrent=SharedTorrent.fromFile(					new File(torrentPath),					new File(sourceFileParentPath));						/**2.初始化客户端,并注册监听*/    		BtClient_Client = new Client(Client.getIPv4Address("eth0"),BtClient_ShareTorrent);			/**3.连接tracker服务器做种或下载*/    		BtClient_Client.share();			if (ClientState.ERROR.equals(BtClient_Client.getState())) {				System.exit(1);			}		} catch (Exception e) {			Log.e(TAG, "Fatal error: "+ e.getMessage(), e);			System.exit(2);		}		return BtClient_Client;	}

 

2.在第2步,初始化客户端时,首先注册一个ConnectionHandler连接通道,等待其他peers来连接,这样就相当于自己变成一个服务端(故此既是客户端也是服务端)

/**提供其他peers连接交互的通道*/		this.service = new ConnectionHandler(this.torrent, id, address);		this.service.register(this);

再注册announce的通道负责去请求Tracker服务器

this.announce = new Announce(this.torrent, this.self);		this.announce.register(this);

 

/**	 * Initialize the BitTorrent client.	 *	 * @param address The address to bind to.	 * @param torrent The torrent to download and share.	 */	public Client(InetAddress address, SharedTorrent torrent)		throws UnknownHostException, IOException {		this.torrent = torrent;		this.state = ClientState.WAITING;		String id = Client.BITTORRENT_ID_PREFIX + UUID.randomUUID()			.toString().split("-")[4];		// Initialize the incoming connection handler and register ourselves to		// it.				/**提供其他peers连接交互的通道*/		this.service = new ConnectionHandler(this.torrent, id, address);		this.service.register(this);		this.self = new Peer(			this.service.getSocketAddress()				.getAddress().getHostAddress(),			(short)this.service.getSocketAddress().getPort(),			ByteBuffer.wrap(id.getBytes(Torrent.BYTE_ENCODING)));		// Initialize the announce request thread, and register ourselves to it		// as well.		this.announce = new Announce(this.torrent, this.self);		this.announce.register(this);		logger.info("BitTorrent client [{}] for {} started and " +			"listening at {}:{}...",			new Object[] {				this.self.getShortHexPeerId(),				this.torrent.getName(),				this.self.getIp(),				this.self.getPort()			});		//		this.peers = new ConcurrentHashMap
(); this.connected = new ConcurrentHashMap
(); this.random = new Random(System.currentTimeMillis()); }

 

客户端初始化完成后,调用share()启动Client线程服务,在线程run()方法中,继续启动刚注册的几个线程

 

/**3.连接tracker服务器做种或下载*/    		BtClient_Client.share();

 

 

具体代码请看到Client.java里的run()方法

3.第三步,得到tracker服务器的响应,在代码com.turn.ttorrent.announce.HTTPTrackerClient.java中line:106行

HttpURLConnection conn = null;		InputStream in = null;		try {			//连接tracker服务器,成功返回200状态码			conn = (HttpURLConnection)target.openConnection();			in = conn.getInputStream();					} catch (IOException ioe) {			if (conn != null) {				in = conn.getErrorStream();			}		}		// At this point if the input stream is null it means we have neither a		// response body nor an error stream from the server. No point in going		// any further.		if (in == null) {			throw new AnnounceException("No response or unreachable tracker!");		}		try {			//从流中得到tracker返回的消息			ByteArrayOutputStream baos = new ByteArrayOutputStream();			baos.write(in);			// Parse and handle the response			HTTPTrackerMessage message =				HTTPTrackerMessage.parse(ByteBuffer.wrap(baos.toByteArray()));			this.handleTrackerAnnounceResponse(message, inhibitEvents);		} catch (IOException ioe) {			throw new AnnounceException("Error reading tracker response!", ioe);		} catch (MessageValidationException mve) {			throw new AnnounceException("Tracker message violates expected " +				"protocol (" + mve.getMessage() + ")", mve);		} finally {			// Make sure we close everything down at the end to avoid resource			// leaks.			try {				in.close();			} catch (IOException ioe) {				logger.warn("Problem ensuring error stream closed!", ioe);			}			// This means trying to close the error stream as well.			InputStream err = conn.getErrorStream();			if (err != null) {				try {					err.close();				} catch (IOException ioe) {					logger.warn("Problem ensuring error stream closed!", ioe);				}			}		}

 

这个http的请求格式如:

192.168.21.154是android机子的ip,也就是做种者的ip,tracker服务器我是在192.168.21.91上搭的,也就是我电脑的ip,上面图片就是tracker回显出的请求信息

在info_hash后的参数全部都是封装在这个target对象中

conn = (HttpURLConnection)target.openConnection();

 

之后再管道流中得到一个tracker响应的被bencoding编码过的数据,再解析出peers列表

 

//从流中得到tracker返回的消息			ByteArrayOutputStream baos = new ByteArrayOutputStream();			baos.write(in);			// Parse and handle the response			HTTPTrackerMessage message =				HTTPTrackerMessage.parse(ByteBuffer.wrap(baos.toByteArray()));			this.handleTrackerAnnounceResponse(message, inhibitEvents);

 

此时是做种,所有tracker上的信息之后seeder的信息,即做种者的信息

4、5、6:之后,就是peers连接tracker得到peers列表,里面包含peers自己和seeder的信息,与seeder建立对等连接,交换数据。

 

转载于:https://my.oschina.net/blackylin/blog/113281

你可能感兴趣的文章
Linux下修改PATH的方法
查看>>
JdbcTemplate使用总结
查看>>
一道腾讯面试题的思考:到底谁会赢?
查看>>
flex
查看>>
paip 自定义输入法多多输入法词库的备份导出以及导入
查看>>
创业公司
查看>>
asp.net页面与页面之间传参数值
查看>>
Jsp中使用数据库连接池.
查看>>
AndroidUI设计之布局-详细解析布局实现
查看>>
用 Python 脚本实现对 Linux 服务器的监控
查看>>
Windows phone 8 学习笔记(1) 触控输入
查看>>
Python补充03 Python内置函数清单
查看>>
分布式缓存服务器设计原理
查看>>
Eclipse换常用的快捷键
查看>>
Windows Phone 8.1 新特性 - 控件之列表选择控件
查看>>
线程同步:互斥锁,条件变量,信号量
查看>>
【cocos2d-x 3.0-Mac配置篇】
查看>>
学习学习
查看>>
提升jQuery开发技能的教程
查看>>
Android系统自带样式(@android:style/) (转)
查看>>