1 Star 5 Fork 1

xuemy / fastdht

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
dht.go 4.19 KB
一键复制 编辑 原始数据 按行查看 历史
xuemy 提交于 2015-03-03 13:25 . 最新的可以直接运行的dht爬虫
package fastdht
import (
"fmt"
log "github.com/golang/glog"
"net"
"strconv"
)
var _ = log.Info
var _ = fmt.Println
var _ = net.Listen
var BOOTSTRAP []string = []string{
"67.215.246.10:6881",
"212.129.33.50:6881",
"82.221.103.244:6881"}
func NewDHT(ip string, port int) (dht *DHT, err error) {
dht = new(DHT)
dht.Ip = ip
dht.Port = port
dht.NodeId = randNodeId()
table := newTable(maxTableNum)
taddress := ip + ":" + strconv.Itoa(port)
address, _ := net.ResolveUDPAddr("udp4", taddress)
dht.Address = address
dht.Table = table
return
}
func (dht *DHT) sendFindNode(node *Node) {
query := new(queryMessage)
query.T = tranId()
query.Q = "find_node"
query.Y = "q"
var nid string
if node.nid != nil {
nid = Neighbor(node.nid.String(), dht.NodeId.String())
} else {
nid = randNodeId().String()
}
query.A = map[string]interface{}{
"id": nid,
"target": randNodeId().String(),
}
log.V(5).Infof("Port:%d 正在向地址%s发出Find Node请求", dht.Port, node.address.String())
sendMsg(dht.Conn, node.address, query)
}
func (dht *DHT) replyPing(node *Node) {
response := new(replyMessage)
response.T = node.tid
response.Y = "r"
response.R = map[string]interface{}{
"id": dht.NodeId.String(),
}
log.V(5).Infof("Port:%d 正在回复从地址%s发出Ping请求", dht.Port, node.address.String())
sendMsg(dht.Conn, node.address, response)
}
func (dht *DHT) replyFindNode(node *Node) {
response := new(replyMessage)
response.T = node.tid
response.Y = "r"
response.R = map[string]interface{}{
"id": dht.NodeId.String(),
"nodes": "",
}
log.V(5).Infof("Port:%d 正在回复从地址%s发出FindNode请求", dht.Port, node.address.String())
sendMsg(dht.Conn, node.address, response)
}
func (dht *DHT) replyGetPeers(node *Node, infohash string, out chan string) {
token := infohash[:tokenLength]
response := new(replyMessage)
response.T = node.tid
response.Y = "r"
response.R = map[string]interface{}{
"id": Neighbor(infohash, dht.NodeId.String()),
"nodes": "",
"token": token,
}
out <- infohash
log.V(5).Infof("Port:%d 正在回复从地址%s发出GetPeers请求", dht.Port, node.address.String())
sendMsg(dht.Conn, node.address, response)
}
func (dht *DHT) replyAnnouncePeer(node *Node, infohash string, token string, out chan string) {
if token == infohash[:tokenLength] {
out <- infohash
}
response := new(replyMessage)
response.T = node.tid
response.Y = "r"
response.R = map[string]interface{}{
"id": Neighbor(node.nid.String(), dht.NodeId.String()),
}
log.V(5).Infof("Port:%d 正在回复从地址%s发出AnnouncePeer请求", dht.Port, node.address.String())
sendMsg(dht.Conn, node.address, response)
}
func (dht *DHT) replyError(node *Node) {
response := new(errorMessage)
response.T = node.tid
response.Y = "e"
response.E = []interface{}{
202, "Server Error",
}
sendMsg(dht.Conn, node.address, response)
}
func (dht *DHT) processPacket(p packetType, out chan string) {
r, _ := decodeMsg(p.b)
tid := r.T
switch {
case r.Y == "r":
nodestring := r.R.Nodes
nodes := parseNodesString(nodestring)
for k, v := range nodes {
node := new(Node)
node.nid = Id(k)
node.tid = tid
node.address = v
dht.Table <- node
}
case r.Y == "q":
node := new(Node)
node.tid = tid
node.address = p.address
node.nid = Id(r.A.Id)
switch r.Q {
case "ping":
dht.replyPing(node)
case "find_node":
dht.replyError(node)
// dht.replyFindNode(node)
case "get_peers":
infohash := r.A.InfoHash
dht.replyGetPeers(node, infohash, out)
case "announce_peer":
infohash := r.A.InfoHash
token := r.A.Token
dht.replyAnnouncePeer(node, infohash, token, out)
}
}
}
func (dht *DHT) Run(out chan string) {
packetChan := make(chan packetType)
conn, err := listen(dht.Address)
if err != nil {
log.Fatal(err)
}
dht.Conn = conn
dht.Port = conn.LocalAddr().(*net.UDPAddr).Port
go reviceMsg(conn, packetChan)
for _, host := range BOOTSTRAP {
addr, _ := net.ResolveUDPAddr("udp4", host)
node := new(Node)
node.address = addr
dht.Table <- node
}
log.V(1).Infof("开始DHT爬虫,Port:%d", dht.Port)
for {
select {
case node := <-dht.Table:
dht.sendFindNode(node.(*Node))
case p := <-packetChan:
dht.processPacket(p, out)
}
}
}
Go
1
https://gitee.com/xuemy/fastdht.git
git@gitee.com:xuemy/fastdht.git
xuemy
fastdht
fastdht
master

搜索帮助