mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-09 18:10:29 +00:00
84 lines
1.9 KiB
Go
84 lines
1.9 KiB
Go
package torrent
|
|
|
|
import (
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/monkeyWie/gopeed/protocol/bt/metainfo"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type Torrent struct {
|
|
PeerID [20]byte
|
|
MetaInfo *metainfo.MetaInfo
|
|
|
|
pieceStates *pieceStates
|
|
peerPool *peerPool
|
|
Path string
|
|
}
|
|
|
|
func NewTorrent(peerID [20]byte, metaInfo *metainfo.MetaInfo) *Torrent {
|
|
torrent := &Torrent{
|
|
PeerID: peerID,
|
|
MetaInfo: metaInfo,
|
|
pieceStates: newPiecesState(metaInfo),
|
|
}
|
|
return torrent
|
|
}
|
|
|
|
func (t *Torrent) Download(path string) {
|
|
t.Path = path
|
|
t.peerPool = newPeerPool(t)
|
|
t.peerPool.fetch()
|
|
|
|
pieceQueueCh := make(chan interface{}, 128)
|
|
defer close(pieceQueueCh)
|
|
downloadedCh := make(chan interface{})
|
|
defer close(downloadedCh)
|
|
|
|
for i := 0; i < len(t.MetaInfo.Info.Pieces); i++ {
|
|
// 加入下载队列
|
|
pieceQueueCh <- nil
|
|
go func(index int) {
|
|
t.pieceStates.setState(index, stateDownloading)
|
|
// 一直下载到成功
|
|
for {
|
|
peer := t.peerPool.get()
|
|
if peer == nil {
|
|
time.Sleep(time.Second * 10)
|
|
continue
|
|
}
|
|
pc := newPeerConn(t, peer)
|
|
err := pc.ready()
|
|
if err != nil {
|
|
t.peerPool.unavailable(peer)
|
|
} else {
|
|
err = pc.downloadPiece(index)
|
|
if err != nil {
|
|
log.Debugf("piece %d download fail:%s", index, err.Error())
|
|
// 下载失败
|
|
t.peerPool.unavailable(peer)
|
|
if errors.Is(err, errPieceCheckFailed) {
|
|
// piece校验失败,需要重新下载过一遍,清空block记录
|
|
t.pieceStates.clearBlocks(index)
|
|
}
|
|
continue
|
|
} else {
|
|
// 下载完成
|
|
t.pieceStates.setState(index, stateFinish)
|
|
t.peerPool.release(peer)
|
|
log.Debugf("piece %d download success,total:%d,left:%d", index, t.pieceStates.size(), t.pieceStates.getLeft())
|
|
if t.pieceStates.isDone() {
|
|
downloadedCh <- nil
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
<-pieceQueueCh
|
|
}(i)
|
|
}
|
|
<-downloadedCh
|
|
log.Debug("download end")
|
|
}
|