Skip to content

Commit

Permalink
单个peer的文件下载实现
Browse files Browse the repository at this point in the history
  • Loading branch information
monkeyWie committed Oct 8, 2019
1 parent fe01384 commit 15a4b6d
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 48 deletions.
57 changes: 42 additions & 15 deletions down/bt/metainfo/metainfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ type MetaInfo struct {
UrlList []string `json:"url-list"`
Info *Info `json:"info"`

ExtraInfo `json:"-"`
infoHash [20]byte `json:"-"`
totalSize uint64 `json:"-"`
fileDetails []FileDetail `json:"-"`
}

type Info struct {
Expand All @@ -34,13 +36,15 @@ type Info struct {
}

type File struct {
Length uint64 `json:"length"`
Path string `json:"path"`
Length uint64 `json:"length"`
Path []string `json:"path"`
}

type ExtraInfo struct {
InfoHash [20]byte
TotalSize uint64
type FileDetail struct {
Length uint64
Path []string
Begin int64
End int64
}

func ParseFromFile(path string) (*MetaInfo, error) {
Expand All @@ -63,7 +67,7 @@ func ParseFromFile(path string) (*MetaInfo, error) {
// encode info hash
info := btDecode["info"].(map[string]interface{})
infoBtEncode := bencode.Encode(info)
metaInfo.InfoHash = sha1.Sum(infoBtEncode[:])
metaInfo.infoHash = sha1.Sum(infoBtEncode[:])
// Split pieces hash
pieces := info["pieces"].(string)
if pieces != "" {
Expand All @@ -75,33 +79,56 @@ func ParseFromFile(path string) (*MetaInfo, error) {
}
}
}
metaInfo.TotalSize = getTotalSize(&metaInfo)
calcFileSize(&metaInfo)
return &metaInfo, nil
}

// 获取某个分片的大小
func (metaInfo *MetaInfo) GetPieceSize(index int) uint64 {
// 是否为最后一个分片
if index == len(metaInfo.Info.Pieces)-1 {
size := metaInfo.TotalSize % metaInfo.Info.PieceLength
size := metaInfo.totalSize % metaInfo.Info.PieceLength
if size > 0 {
return size
}
}
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 len(metaInfo.Info.Files) > 0 {
fileCount := len(metaInfo.Info.Files)
if fileCount > 0 {
metaInfo.fileDetails = make([]FileDetail, fileCount)
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
}
return length
metaInfo.totalSize = length
} else {
return metaInfo.Info.Length
metaInfo.totalSize = metaInfo.Info.Length
}
}
return 0
}
3 changes: 2 additions & 1 deletion down/bt/metainfo/metainfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ func TestParseFromFile(t *testing.T) {
if err != nil {
panic(err)
}
fmt.Println(metaInfo)
fmt.Printf("%+v\n", metaInfo)
fmt.Printf("%+v\n", metaInfo.Info.Files)
}
4 changes: 2 additions & 2 deletions down/bt/peer/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ type Message struct {
ID ID
}

func (msg Message) Encode() []byte {
func (msg *Message) Encode() []byte {
buf := make([]byte, 5)
binary.BigEndian.PutUint32(buf, msg.Length)
buf[4] = byte(msg.ID)
return buf
}

func (msg Message) Decode(buf []byte) {
func (msg *Message) Decode(buf []byte) {
msg.Length = binary.BigEndian.Uint32(buf)
msg.ID = ID(buf[4])
}
Expand Down
7 changes: 4 additions & 3 deletions down/bt/peer/message/msg_bitfield.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package message

// bitfield: <len=0001+X><id=5><bitfield>
type Bitfield struct {
Message
*Message
payload []byte
}

func NewBitfield(payload []byte) *Bitfield {
return &Bitfield{
Message: Message{
Message: &Message{
Length: uint32(len(payload) + 1),
ID: IdBitfield,
},
Expand All @@ -21,8 +21,9 @@ func (b *Bitfield) Encode() []byte {
}

func (b *Bitfield) Decode(buf []byte) Serialize {
b.Message = &Message{}
b.Message.Decode(buf)
copy(b.payload, buf[5:])
b.payload = buf[5:]
return b
}

Expand Down
32 changes: 25 additions & 7 deletions down/bt/peer/message/msg_piece.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
package message

import "io"
import "encoding/binary"

// piece: <len=0009+X><id=7><index><begin><block>
type Piece struct {
Message
*Message
Index 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{
Message: Message{
Length: 9 + length,
Message: &Message{
Length: 9 + uint32(len(block)),
ID: IdPiece,
},
Index: index,
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
}
4 changes: 2 additions & 2 deletions down/bt/peer/message/msg_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ func NewRequest(index uint32, begin uint32, length uint32) *Request {

func (r *Request) Encode() []byte {
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[8:], r.Length)
binary.BigEndian.PutUint32(buf[8:12], r.Length)
return append(r.Message.Encode(), buf...)
}

Expand Down
Loading

0 comments on commit 15a4b6d

Please sign in to comment.