向tracker服务器发送信息

client向tracker发一个HTTP的GET请求,并把它自己的信息放在GET的参数中;这个请求的大致意思是:我是xxx(一个唯一的id),我想下载yyy文件,我的ip是aaa,我用的端口是bbb。。。
  tracker对所有下载者的信息进行维护,当它收到一个请求后,首先把对方的信息记录下来(如果已经记录在案,那么就检查是否需要更新),然后将一部分(并非全部,根据设置的参数已经下载者的请求)参与下载同一个文件(一个tracker服务器可能同时维护多个文件的下载)的下载者的信息返回给对方。
  Client在收到tracker的响应后,就能获取其它下载者的信息,那么它就可以根据这些信息,与其它下载者建立连接,从它们那里下载文件片断。

能不能给个示例应该发送什么样的消息,又收到什么样的消息?

参考一下这个代码:
http://www.tuicool.com/articles/z6N363

握手消息是一个长度固定为68 字节的消息。消息的格式如下:

pstrlen pstr 的长度,该值固定为19
pstr BitTorrent 协议的关键字,即“BitTorrent protocol”
reserved 占8 字节,用于扩展BT 协议,一般这8 字节都设置为0。有些BT 软件对BT 协议进行了某些扩展,因此可能看到有些peer 发来的握手消息这8 个字节不全为0,不过不必理会,这不会影响正常的通信
info_hash 与发往Tracker 的GET 请求中的info_hash 为同一个值,长度固定为20 字节
keep_alive 消息:
keep_alive 消息的长度固定,为4 字节,它没有消息编号和负载。如果一段时间内客户端与peer 没有交换任何消息,则与这个peer 的连接将被关闭。keep_alive 消息用于维持这个连接,通常如果2 分钟内没有向peer 发送任何消息,则发送一个keep_alive 消息。
choke 消息:
choke 消息的长度固定,为5 字节,消息长度占4 个字节,消息编号占1 个字节,没有负载。该消息的功能是,发出该消息的peer 将接收该消息的peer 阻塞,暂时不允许其下载自己的数据。
unchoke 消息:
unchoke 消息的长度固定,为5 字节,消息长度占4 个字节,消息编号占1 个字节,没有负载。客户端每隔一定的时间,通常为10 秒,计算一次各个peer 的下载速度,如果某peer 被解除阻塞,则发送unchoke 消息。如果某个peer 原先是解除阻塞的,而此次被阻塞,则发送choke 消息。
interested 消息:
interested 消息的长度固定,为5 字节,消息长度占4 个字节,消息编号占1 个字节,没有负载。当客户端收到某peer 的have 消息时,如果发现peer 拥有了客户端没有的piece,则发送interested消息告知该peer,客户端对它感兴趣。
not interested 消息:
not interested 消息的长度固定,为5 字节,消息长度占4 个字节,消息编号占1 个字节,没有负载。当客户端下载了某个piece,如果发现客户端拥有了这个piece 后,某个peer 拥有的所有piece,客户端都拥有,则发送not interested 消息给该peer。
have 消息:
have 消息的长度固定,为9 字节,消息长度占4 个字节,消息编号占1 个字节,负载为4 个字节。负载为一个整数,指明下标为index 的piece,peer 已经拥有。每当客户端下载了一个piece,即将该piece 的下标作为have 消息的负载构造have 消息,并把该消息发送给所有与客户端建立连接的peer。
bitfield 消息:
bitfield 消息的长度不固定,其中X 是bitfield(即位图)的长度。当客户端与peer 交换握手消息之后,就交换位图。位图中,每个piece 占一位,若该位的值为1,则表明已经拥有该piece;为0则表明该piece 尚未下载。具体而言,假定某共享文件共拥有801 个piece,则位图为101 个字节,位图的第一个字节的最高位指明第一个piece 是否拥有,位图的第一个字节的第二高位指明第二个piece 是否拥有,依此类推。对于第801 个piece,需要单独一个字节,该字节的最高位指明第801 个piece 是否已被下载,其余的7 位放弃不予使用。
request 消息:
request 消息的长度固定,为17 个字节,index 是piece 的索引,begin 是piece 内的偏移,length是请求peer 发送的数据的长度。当客户端收到某个peer 发来的unchoke 消息后,即构造request消息,向该peer 发送数据请求。前面提到,peer 之间交换数据是以slice(长度为16KB 的块)为单位的,因此request 消息中length 的值一般为16K。对于一个256KB 的piece,客户端分16 次下载,每次下载一个16K 的slice。
piece 消息:
piece 消息是另外一个长度不固定的消息,长度前缀中的9 是id、index、begin 的长度总和,index和begin 固定为4 字节,X 为block 的长度,一般为16K。因此对于piece 消息,长度前缀加上id 通常为00 00 40 09 07。当客户端收到某个peer 的request 消息后,如果判定当前未将该peer 阻塞,且peer请求的slice,客户端已经下载,则发送piece 消息将文件数据上传给该peer。
cancel 消息:
cancel 消息的长度固定,为17 个字节,len、index、begin、length 都占4 字节。它与request消息对应,作用刚好相反,用于取消对某个slice 的数据请求。如果客户端发现,某个piece 中的slice,客户端已经下载,而客户端又向其他peer 发送了对该slice 的请求,则向该peer 发送cancel消息,以取消对该slice 的请求。事实上,如果算法设计合理,基本不用发送cancel 消息,只在某些特殊的情况下才需要发送cancel 消息。
port 消息:
port 消息的长度固定,为7 字节,其中listen-port 占两个字节。该消息只在支持DHT 的客户端中才会使用,用于指明DHT 监听的端口号,一般不必理会,收到该消息时,直接丢弃即可。