diff --git a/bitfield/bitfield.go b/bitfield/bitfield.go new file mode 100644 index 0000000..b7e4bda --- /dev/null +++ b/bitfield/bitfield.go @@ -0,0 +1,3 @@ +package bitfield + +type Bitfield []byte diff --git a/client/client.go b/client/client.go new file mode 100644 index 0000000..484dfda --- /dev/null +++ b/client/client.go @@ -0,0 +1,33 @@ +package client + +import ( + "BitTorrent-Client/bitfield" + "BitTorrent-Client/peers" + "net" + "time" +) + +type Client struct { + Conn net.Conn + Choked bool + Bitfield bitfield.Bitfield + peer peers.Peer + infoHash [20]byte + peerID [20]byte +} + +func New(peer peers.Peer, peerID, infoHash [20]byte) (*Client, error) { + conn, err := net.DialTimeout("tcp", peer.String(), 3*time.Second) + if err != nil { + return nil, err + } + return &Client{ + Conn: conn, + Choked: true, + peer: peer, + infoHash: infoHash, + peerID: peerID, + }, nil +} + +// Read reads and consumes a message from the connection diff --git a/hand_shake/hand_shake.go b/hand_shake/hand_shake.go new file mode 100644 index 0000000..c7bdf87 --- /dev/null +++ b/hand_shake/hand_shake.go @@ -0,0 +1,20 @@ +package handshake + +// A Handshake is a special message that a peer uses to identify itself +type Handshake struct { + Pstr string + InfoHash [20]byte + PeerID [20]byte +} + +// Serialize serializes the handshake to a buffer +func (h *Handshake) Serialize() []byte { + buf := make([]byte, len(h.Pstr)+49) + buf[0] = byte(len(h.Pstr)) + curr := 1 + curr += copy(buf[curr:], h.Pstr) + curr += copy(buf[curr:], make([]byte, 8)) // 8 reserved bytes + curr += copy(buf[curr:], h.InfoHash[:]) + curr += copy(buf[curr:], h.PeerID[:]) + return buf +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..8614812 --- /dev/null +++ b/main.go @@ -0,0 +1,17 @@ +package main + +import ( + torrentfile "BitTorrent-Client/torrent_file" + "log" + "os" +) + +func main() { + inPath := os.Args[1] + + _, err := torrentfile.Open(inPath) + if err != nil { + log.Fatal(err) + } + +} diff --git a/peers/peers.go b/peers/peers.go index ddc21cd..27dec63 100644 --- a/peers/peers.go +++ b/peers/peers.go @@ -4,6 +4,7 @@ import ( "encoding/binary" "fmt" "net" + "strconv" ) type Peer struct { @@ -27,3 +28,6 @@ func Unmarshal(peersBin []byte) ([]Peer, error) { } return peers, nil } +func (p Peer) String() string { + return net.JoinHostPort(p.IP.String(), strconv.Itoa(int(p.Port))) +} diff --git a/torrent_file/torrent_file.go b/torrent_file/torrent_file.go index 8c34de6..dc45f37 100644 --- a/torrent_file/torrent_file.go +++ b/torrent_file/torrent_file.go @@ -1,7 +1,7 @@ package torrentfile import ( - "io" + "os" "github.com/jackpal/bencode-go" ) @@ -29,11 +29,15 @@ type bencodeTorrent struct { } // Open parses a torrent file -func Open(r io.Reader) (*bencodeTorrent, error) { - bto := bencodeTorrent{} - err := bencode.Unmarshal(r, &bto) +func Open(path string) (TorrentFile, error) { + file, err := os.Open(path) if err != nil { - return nil, err + return TorrentFile{}, err } - return &bto, nil + defer file.Close() + + bto := bencodeTorrent{} + err = bencode.Unmarshal(file, &bto) + return TorrentFile{}, err + }