mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-14 20:33:41 +00:00
单个peer的文件下载实现
This commit is contained in:
1 parent
fe0138440f
commit
15a4b6ddc4
9 files changed
+179
-48
No files matched your search
@@ -22,7 +22,9 @@ type MetaInfo struct {
|
|||||||
UrlList []string `json:"url-list"`
|
UrlList []string `json:"url-list"`
|
||||||
Info *Info `json:"info"`
|
Info *Info `json:"info"`
|
||||||
|
|
||||||
ExtraInfo `json:"-"`
|
infoHash [20]byte `json:"-"`
|
||||||
|
totalSize uint64 `json:"-"`
|
||||||
|
fileDetails []FileDetail `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Info struct {
|
type Info struct {
|
||||||
@@ -34,13 +36,15 @@ type Info struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type File struct {
|
type File struct {
|
||||||
Length uint64 `json:"length"`
|
Length uint64 `json:"length"`
|
||||||
Path string `json:"path"`
|
Path []string `json:"path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExtraInfo struct {
|
type FileDetail struct {
|
||||||
InfoHash [20]byte
|
Length uint64
|
||||||
TotalSize uint64
|
Path []string
|
||||||
|
Begin int64
|
||||||
|
End int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseFromFile(path string) (*MetaInfo, error) {
|
func ParseFromFile(path string) (*MetaInfo, error) {
|
||||||
@@ -63,7 +67,7 @@ func ParseFromFile(path string) (*MetaInfo, error) {
|
|||||||
// encode info hash
|
// encode info hash
|
||||||
info := btDecode["info"].(map[string]interface{})
|
info := btDecode["info"].(map[string]interface{})
|
||||||
infoBtEncode := bencode.Encode(info)
|
infoBtEncode := bencode.Encode(info)
|
||||||
metaInfo.InfoHash = sha1.Sum(infoBtEncode[:])
|
metaInfo.infoHash = sha1.Sum(infoBtEncode[:])
|
||||||
// Split pieces hash
|
// Split pieces hash
|
||||||
pieces := info["pieces"].(string)
|
pieces := info["pieces"].(string)
|
||||||
if pieces != "" {
|
if pieces != "" {
|
||||||
@@ -75,7 +79,7 @@ func ParseFromFile(path string) (*MetaInfo, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
metaInfo.TotalSize = getTotalSize(&metaInfo)
|
calcFileSize(&metaInfo)
|
||||||
return &metaInfo, nil
|
return &metaInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +87,7 @@ func ParseFromFile(path string) (*MetaInfo, error) {
|
|||||||
func (metaInfo *MetaInfo) GetPieceSize(index int) uint64 {
|
func (metaInfo *MetaInfo) GetPieceSize(index int) uint64 {
|
||||||
// 是否为最后一个分片
|
// 是否为最后一个分片
|
||||||
if index == len(metaInfo.Info.Pieces)-1 {
|
if index == len(metaInfo.Info.Pieces)-1 {
|
||||||
size := metaInfo.TotalSize % metaInfo.Info.PieceLength
|
size := metaInfo.totalSize % metaInfo.Info.PieceLength
|
||||||
if size > 0 {
|
if size > 0 {
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
@@ -91,17 +95,40 @@ func (metaInfo *MetaInfo) GetPieceSize(index int) uint64 {
|
|||||||
return metaInfo.Info.PieceLength
|
return metaInfo.Info.PieceLength
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTotalSize(metaInfo *MetaInfo) uint64 {
|
// 获取所有文件的大小
|
||||||
|
func (metaInfo *MetaInfo) GetTotalSize() uint64 {
|
||||||
|
return metaInfo.totalSize
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取info hash
|
||||||
|
func (metaInfo *MetaInfo) GetInfoHash() [20]byte {
|
||||||
|
return metaInfo.infoHash
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有文件的开始偏移字节
|
||||||
|
func (metaInfo *MetaInfo) GetFileDetails() []FileDetail {
|
||||||
|
return metaInfo.fileDetails
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算所有文件的大小
|
||||||
|
func calcFileSize(metaInfo *MetaInfo) {
|
||||||
if metaInfo.Info != nil {
|
if metaInfo.Info != nil {
|
||||||
if len(metaInfo.Info.Files) > 0 {
|
fileCount := len(metaInfo.Info.Files)
|
||||||
|
if fileCount > 0 {
|
||||||
|
metaInfo.fileDetails = make([]FileDetail, fileCount)
|
||||||
var length uint64
|
var length uint64
|
||||||
for _, f := range metaInfo.Info.Files {
|
for i, f := range metaInfo.Info.Files {
|
||||||
|
metaInfo.fileDetails[i] = FileDetail{
|
||||||
|
Length: f.Length,
|
||||||
|
Path: f.Path,
|
||||||
|
Begin: int64(length),
|
||||||
|
End: int64(length + f.Length),
|
||||||
|
}
|
||||||
length += f.Length
|
length += f.Length
|
||||||
}
|
}
|
||||||
return length
|
metaInfo.totalSize = length
|
||||||
} else {
|
} else {
|
||||||
return metaInfo.Info.Length
|
metaInfo.totalSize = metaInfo.Info.Length
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
@@ -10,5 +10,6 @@ func TestParseFromFile(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Println(metaInfo)
|
fmt.Printf("%+v\n", metaInfo)
|
||||||
|
fmt.Printf("%+v\n", metaInfo.Info.Files)
|
||||||
}
|
}
|
||||||
@@ -29,14 +29,14 @@ type Message struct {
|
|||||||
ID ID
|
ID ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg Message) Encode() []byte {
|
func (msg *Message) Encode() []byte {
|
||||||
buf := make([]byte, 5)
|
buf := make([]byte, 5)
|
||||||
binary.BigEndian.PutUint32(buf, msg.Length)
|
binary.BigEndian.PutUint32(buf, msg.Length)
|
||||||
buf[4] = byte(msg.ID)
|
buf[4] = byte(msg.ID)
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg Message) Decode(buf []byte) {
|
func (msg *Message) Decode(buf []byte) {
|
||||||
msg.Length = binary.BigEndian.Uint32(buf)
|
msg.Length = binary.BigEndian.Uint32(buf)
|
||||||
msg.ID = ID(buf[4])
|
msg.ID = ID(buf[4])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ package message
|
|||||||
|
|
||||||
// bitfield: <len=0001+X><id=5><bitfield>
|
// bitfield: <len=0001+X><id=5><bitfield>
|
||||||
type Bitfield struct {
|
type Bitfield struct {
|
||||||
Message
|
*Message
|
||||||
payload []byte
|
payload []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBitfield(payload []byte) *Bitfield {
|
func NewBitfield(payload []byte) *Bitfield {
|
||||||
return &Bitfield{
|
return &Bitfield{
|
||||||
Message: Message{
|
Message: &Message{
|
||||||
Length: uint32(len(payload) + 1),
|
Length: uint32(len(payload) + 1),
|
||||||
ID: IdBitfield,
|
ID: IdBitfield,
|
||||||
},
|
},
|
||||||
@@ -21,8 +21,9 @@ func (b *Bitfield) Encode() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bitfield) Decode(buf []byte) Serialize {
|
func (b *Bitfield) Decode(buf []byte) Serialize {
|
||||||
|
b.Message = &Message{}
|
||||||
b.Message.Decode(buf)
|
b.Message.Decode(buf)
|
||||||
copy(b.payload, buf[5:])
|
b.payload = buf[5:]
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,41 @@
|
|||||||
package message
|
package message
|
||||||
|
|
||||||
import "io"
|
import "encoding/binary"
|
||||||
|
|
||||||
// piece: <len=0009+X><id=7><index><begin><block>
|
// piece: <len=0009+X><id=7><index><begin><block>
|
||||||
type Piece struct {
|
type Piece struct {
|
||||||
Message
|
*Message
|
||||||
Index uint32
|
Index uint32
|
||||||
Begin uint32
|
Begin uint32
|
||||||
Block io.Reader
|
Block []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPiece(index uint32, begin uint32, reader io.Reader, length uint32) *Piece {
|
func NewPiece(index uint32, begin uint32, block []byte) *Piece {
|
||||||
return &Piece{
|
return &Piece{
|
||||||
Message: Message{
|
Message: &Message{
|
||||||
Length: 9 + length,
|
Length: 9 + uint32(len(block)),
|
||||||
ID: IdPiece,
|
ID: IdPiece,
|
||||||
},
|
},
|
||||||
Index: index,
|
Index: index,
|
||||||
Begin: begin,
|
Begin: begin,
|
||||||
Block: io.LimitReader(reader, int64(length)),
|
// Block: io.LimitReader(reader, int64(length)),
|
||||||
|
Block: block,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Piece) Encode() []byte {
|
||||||
|
buf := make([]byte, 8)
|
||||||
|
binary.BigEndian.PutUint32(buf[:4], p.Index)
|
||||||
|
binary.BigEndian.PutUint32(buf[4:8], p.Begin)
|
||||||
|
buf = append(buf, p.Block...)
|
||||||
|
return append(p.Message.Encode(), buf...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Piece) Decode(buf []byte) Serialize {
|
||||||
|
p.Message = &Message{}
|
||||||
|
p.Message.Decode(buf)
|
||||||
|
p.Index = binary.BigEndian.Uint32(buf[5:9])
|
||||||
|
p.Begin = binary.BigEndian.Uint32(buf[9:13])
|
||||||
|
p.Block = buf[13:]
|
||||||
|
return p
|
||||||
|
}
|
||||||
@@ -26,9 +26,9 @@ func NewRequest(index uint32, begin uint32, length uint32) *Request {
|
|||||||
|
|
||||||
func (r *Request) Encode() []byte {
|
func (r *Request) Encode() []byte {
|
||||||
buf := make([]byte, 12)
|
buf := make([]byte, 12)
|
||||||
binary.BigEndian.PutUint32(buf[:4], r.Index)
|
binary.BigEndian.PutUint32(buf[0:4], r.Index)
|
||||||
binary.BigEndian.PutUint32(buf[4:8], r.Begin)
|
binary.BigEndian.PutUint32(buf[4:8], r.Begin)
|
||||||
binary.BigEndian.PutUint32(buf[8:], r.Length)
|
binary.BigEndian.PutUint32(buf[8:12], r.Length)
|
||||||
return append(r.Message.Encode(), buf...)
|
return append(r.Message.Encode(), buf...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,15 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/cenkalti/mse"
|
"github.com/cenkalti/mse"
|
||||||
|
"github.com/monkeyWie/gopeed/down/bt/metainfo"
|
||||||
"github.com/monkeyWie/gopeed/down/bt/peer"
|
"github.com/monkeyWie/gopeed/down/bt/peer"
|
||||||
"github.com/monkeyWie/gopeed/down/bt/peer/message"
|
"github.com/monkeyWie/gopeed/down/bt/peer/message"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type peerState struct {
|
type peerState struct {
|
||||||
@@ -32,12 +36,13 @@ type peerState struct {
|
|||||||
// 使用MSE加密来避免运营商对bt流量的封锁,基本上现在市面上BT客户端都默认开启了,不用MSE的话很多Peer拒绝连接
|
// 使用MSE加密来避免运营商对bt流量的封锁,基本上现在市面上BT客户端都默认开启了,不用MSE的话很多Peer拒绝连接
|
||||||
// see http://wiki.vuze.com/w/Message_Stream_Encryption
|
// see http://wiki.vuze.com/w/Message_Stream_Encryption
|
||||||
func (ps *peerState) dialMse() error {
|
func (ps *peerState) dialMse() error {
|
||||||
conn, err := net.Dial("tcp", ps.Address())
|
conn, err := net.DialTimeout("tcp", ps.Address(), time.Second*time.Duration(30))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
mseConn := mse.WrapConn(conn)
|
mseConn := mse.WrapConn(conn)
|
||||||
_, err = mseConn.HandshakeOutgoing(ps.torrent.MetaInfo.InfoHash[:], mse.PlainText, nil)
|
infoHash := ps.torrent.MetaInfo.GetInfoHash()
|
||||||
|
_, err = mseConn.HandshakeOutgoing(infoHash[:], mse.PlainText, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mseConn.Close()
|
mseConn.Close()
|
||||||
return err
|
return err
|
||||||
@@ -50,7 +55,7 @@ func (ps *peerState) dialMse() error {
|
|||||||
// see https://wiki.theory.org/index.php/BitTorrentSpecification#Handshake
|
// see https://wiki.theory.org/index.php/BitTorrentSpecification#Handshake
|
||||||
func (ps *peerState) handshake() (*peer.Handshake, error) {
|
func (ps *peerState) handshake() (*peer.Handshake, error) {
|
||||||
handshakeRes, err := func() (*peer.Handshake, error) {
|
handshakeRes, err := func() (*peer.Handshake, error) {
|
||||||
handshakeReq := peer.NewHandshake([8]byte{}, ps.torrent.MetaInfo.InfoHash, ps.torrent.PeerID)
|
handshakeReq := peer.NewHandshake([8]byte{}, ps.torrent.MetaInfo.GetInfoHash(), ps.torrent.PeerID)
|
||||||
_, err := ps.conn.Write(handshakeReq.Encode())
|
_, err := ps.conn.Write(handshakeReq.Encode())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -104,7 +109,6 @@ func (ps *peerState) download() error {
|
|||||||
// keepalive
|
// keepalive
|
||||||
} else {
|
} else {
|
||||||
messageID := message.ID(buf[4])
|
messageID := message.ID(buf[4])
|
||||||
payload := buf[5:]
|
|
||||||
switch messageID {
|
switch messageID {
|
||||||
case message.IdChoke:
|
case message.IdChoke:
|
||||||
break
|
break
|
||||||
@@ -118,12 +122,12 @@ func (ps *peerState) download() error {
|
|||||||
case message.IdHave:
|
case message.IdHave:
|
||||||
break
|
break
|
||||||
case message.IdBitfield:
|
case message.IdBitfield:
|
||||||
ps.handleBitfield(payload)
|
ps.handleBitfield(buf)
|
||||||
break
|
break
|
||||||
case message.IdRequest:
|
case message.IdRequest:
|
||||||
break
|
break
|
||||||
case message.IdPiece:
|
case message.IdPiece:
|
||||||
ps.handlePiece()
|
ps.handlePiece(buf)
|
||||||
break
|
break
|
||||||
case message.IdCancel:
|
case message.IdCancel:
|
||||||
break
|
break
|
||||||
@@ -133,6 +137,10 @@ func (ps *peerState) download() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func downloadPiece() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (ps *peerState) handleUnchoke() {
|
func (ps *peerState) handleUnchoke() {
|
||||||
ps.peerChoking = false
|
ps.peerChoking = false
|
||||||
// 如果客户端对peer感兴趣并且peer没有choked客户端,就可以开始下载了
|
// 如果客户端对peer感兴趣并且peer没有choked客户端,就可以开始下载了
|
||||||
@@ -148,10 +156,7 @@ func (ps *peerState) handleUnchoke() {
|
|||||||
blockLength := math.Min(2<<13, float64(pieceLength-lastOffset))
|
blockLength := math.Min(2<<13, float64(pieceLength-lastOffset))
|
||||||
ps.write(message.NewRequest(uint32(index), uint32(lastOffset), uint32(blockLength)).Encode())
|
ps.write(message.NewRequest(uint32(index), uint32(lastOffset), uint32(blockLength)).Encode())
|
||||||
lastOffset += uint64(blockLength)
|
lastOffset += uint64(blockLength)
|
||||||
fmt.Println("request piece")
|
|
||||||
}
|
}
|
||||||
// TODO 测试代码
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -159,8 +164,9 @@ func (ps *peerState) handleUnchoke() {
|
|||||||
ps.conn.Close()
|
ps.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *peerState) handleBitfield(payload []byte) {
|
func (ps *peerState) handleBitfield(buf []byte) {
|
||||||
ps.bitfield = message.NewBitfield(payload)
|
ps.bitfield = &message.Bitfield{}
|
||||||
|
ps.bitfield.Decode(buf)
|
||||||
have := ps.getHavePieces(ps.bitfield)
|
have := ps.getHavePieces(ps.bitfield)
|
||||||
if len(have) > 0 {
|
if len(have) > 0 {
|
||||||
// 表示对该peer感兴趣,并且不choked该peer
|
// 表示对该peer感兴趣,并且不choked该peer
|
||||||
@@ -175,8 +181,85 @@ func (ps *peerState) handleBitfield(payload []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理分片下载响应
|
// 处理分片下载响应
|
||||||
func (ps *peerState) handlePiece() {
|
func (ps *peerState) handlePiece(buf []byte) {
|
||||||
fmt.Println("one piece")
|
piece := &message.Piece{}
|
||||||
|
piece.Decode(buf)
|
||||||
|
info := ps.torrent.MetaInfo.Info
|
||||||
|
blockLength := int64(len(piece.Block))
|
||||||
|
pieceBegin := int64(piece.Index)*int64(info.PieceLength) + int64(piece.Begin)
|
||||||
|
// 获取对应要的文件
|
||||||
|
var fileBlocks []fileBlock
|
||||||
|
if len(info.Files) == 0 {
|
||||||
|
// 单文件
|
||||||
|
fileBlocks = append(fileBlocks, fileBlock{
|
||||||
|
filepath: info.Name,
|
||||||
|
fileSeek: pieceBegin,
|
||||||
|
blockBegin: 0,
|
||||||
|
blockEnd: blockLength,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 获取要写入的第一个文件和偏移
|
||||||
|
writeIndex := getWriteFile(pieceBegin, ps.torrent.MetaInfo.GetFileDetails())
|
||||||
|
// block对应种子的偏移
|
||||||
|
blockBegin := pieceBegin
|
||||||
|
// block对应文件的偏移
|
||||||
|
var blockSeek int64 = 0
|
||||||
|
for _, f := range ps.torrent.MetaInfo.GetFileDetails()[writeIndex:] {
|
||||||
|
// 计算文件可剩余写入字节数
|
||||||
|
fileWritable := f.End - blockBegin
|
||||||
|
// 计算block剩余写入字节数
|
||||||
|
blockWritable := blockLength - blockSeek
|
||||||
|
fb := fileBlock{
|
||||||
|
filepath: f.Path[0],
|
||||||
|
fileSeek: blockBegin - f.Begin,
|
||||||
|
blockBegin: blockSeek,
|
||||||
|
}
|
||||||
|
if fileWritable >= blockWritable {
|
||||||
|
// 若够block写入直接跳出循环
|
||||||
|
fb.blockEnd = blockSeek + blockWritable
|
||||||
|
fileBlocks = append(fileBlocks, fb)
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
// 否则计算剩余可写字节数,写入到下一个文件中
|
||||||
|
fb.blockEnd = blockSeek + fileWritable
|
||||||
|
fileBlocks = append(fileBlocks, fb)
|
||||||
|
blockBegin = f.End
|
||||||
|
blockSeek += fileWritable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println(fileBlocks)
|
||||||
|
for _, f := range fileBlocks {
|
||||||
|
func() {
|
||||||
|
name := path.Join("e:/testbt/download", f.filepath)
|
||||||
|
file, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
_, err = file.WriteAt(piece.Block[f.blockBegin:f.blockEnd], f.fileSeek)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取piece对应要写入的文件
|
||||||
|
func getWriteFile(pieceBegin int64, fds []metainfo.FileDetail) int {
|
||||||
|
for i, f := range fds {
|
||||||
|
if f.Begin <= pieceBegin && f.End > pieceBegin {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
type fileBlock struct {
|
||||||
|
filepath string
|
||||||
|
fileSeek int64
|
||||||
|
blockBegin int64
|
||||||
|
blockEnd int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取peer能提供需要下载的文件分片
|
// 获取peer能提供需要下载的文件分片
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func buildTorrent() *Torrent {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
metaInfo.Announce = "udp://tracker.opentrackr.org:1337/announce"
|
metaInfo.Announce = "udp://exodus.desync.com:6969/announce"
|
||||||
metaInfo.AnnounceList = [][]string{}
|
metaInfo.AnnounceList = [][]string{}
|
||||||
return NewTorrent(peer.GenPeerID(), metaInfo)
|
return NewTorrent(peer.GenPeerID(), metaInfo)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,11 +204,11 @@ func (tracker *Tracker) connect(conn *net.UDPConn, timeout int64) (response *udp
|
|||||||
|
|
||||||
func (tracker *Tracker) announce(conn *net.UDPConn, timeout int64, connectionId uint64) (response *udpAnnounceResponse, err error) {
|
func (tracker *Tracker) announce(conn *net.UDPConn, timeout int64, connectionId uint64) (response *udpAnnounceResponse, err error) {
|
||||||
request := newUdpAnnounceRequest(connectionId)
|
request := newUdpAnnounceRequest(connectionId)
|
||||||
request.infoHash = tracker.MetaInfo.InfoHash
|
request.infoHash = tracker.MetaInfo.GetInfoHash()
|
||||||
request.peerID = tracker.PeerID
|
request.peerID = tracker.PeerID
|
||||||
request.downloaded = 0
|
request.downloaded = 0
|
||||||
request.uploaded = 0
|
request.uploaded = 0
|
||||||
request.left = tracker.MetaInfo.TotalSize - request.downloaded
|
request.left = tracker.MetaInfo.GetTotalSize() - request.downloaded
|
||||||
request.event = 0
|
request.event = 0
|
||||||
request.ip = 0
|
request.ip = 0
|
||||||
request.key = 0
|
request.key = 0
|
||||||
@@ -282,12 +282,13 @@ func (tracker *Tracker) httpTracker(url *url.URL) (peers []peer.Peer, err error)
|
|||||||
peerID := tracker.PeerID
|
peerID := tracker.PeerID
|
||||||
|
|
||||||
query := url.Query()
|
query := url.Query()
|
||||||
query.Add("info_hash", string(metaInfo.InfoHash[:]))
|
infoHash := metaInfo.GetInfoHash()
|
||||||
|
query.Add("info_hash", string(infoHash[:]))
|
||||||
query.Add("peer_id", string(peerID[:]))
|
query.Add("peer_id", string(peerID[:]))
|
||||||
query.Add("port", "6882")
|
query.Add("port", "6882")
|
||||||
query.Add("uploaded", "0")
|
query.Add("uploaded", "0")
|
||||||
query.Add("downloaded", "0")
|
query.Add("downloaded", "0")
|
||||||
query.Add("left", strconv.FormatInt(int64(metaInfo.TotalSize), 10))
|
query.Add("left", strconv.FormatInt(int64(metaInfo.GetTotalSize()), 10))
|
||||||
url.RawQuery = query.Encode()
|
url.RawQuery = query.Encode()
|
||||||
request, err := http.NewRequest("GET", url.String(), nil)
|
request, err := http.NewRequest("GET", url.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in new issue
Block a user