-
Notifications
You must be signed in to change notification settings - Fork 2
/
peer.rb
190 lines (153 loc) · 3.42 KB
/
peer.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
require 'socket'
require File.expand_path(File.dirname(__FILE__) + '/bcode')
require File.expand_path(File.dirname(__FILE__) + '/utils')
class Peer
def initialize( host, port)
@host = host
@port = port
@trans = {}
@trans_id_pos = [00, 00]
setLastTime
end
def getinfo
info = {
"host" => @host,
"port" => @port,
}
return info
end
def sendmessage(message, sock, trans_id= nil, lock= nil)
if sock then
bcode = Bencode.new
message["v"] = get_version
if trans_id != nil then
message["t"] = trans_id
end
msg = bcode.encode(message)
#puts "send " + message["q"] + " to " + @host + ":"[email protected]_s
if lock != nil then
lock.synchronize do
#sock.connect(@host, @port )
sock.send(msg, 0, @host, @port)
end
else
#sock.connect(@host, @port )
sock.send(msg, 0, @host, @port)
end
end
end
def get_trans_id(name, info_hash = nil)
@trans_id_pos[0] = @trans_id_pos[0] + 1
if @trans_id_pos[0] == 0xff then
@trans_id_pos[0] = 0
@trans_id_pos[1] = @trans_id_pos[1] + 1
if @trans_id_pos[1] == 0xff then
@trans_id_pos[1] = 0
end
end
trans_id = @trans_id_pos.pack("c*")
@trans[trans_id] = {
"name" => name,
"info_hash" => info_hash,
"access_time" => Time.now.to_i
}
return trans_id
end
def setLastTime
@lastTime = Time.now.to_i #上次通信时间
end
def isbad
@trans.each do |k, v|
if Time.now.to_i - v["access_time"] > 60 then #放弃60秒还没有返回的包
del_tarns(k)
end
end
return (Time.now.to_i - @lastTime ) > (60*15) #15分钟后,就认为这个结点无效
end
def get_trans(trans_id )
ret = @trans[trans_id]
del_tarns(trans_id)
return ret
end
def del_tarns(trans_id)
@trans.delete(trans_id)
end
def setToken(token)
@token = token
end
public
def ping(sock, sender_id, lock = nil)
trans_id = get_trans_id("ping")
msg = {
"y" => "q",
"q" => "ping",
"a" => {"id"=> sender_id}
}
sendmessage(msg, sock, trans_id, lock)
end
def pong(sock, trans_id, sender_id, lock)
msg = {
"y" => "r",
"r" => {
"id" => sender_id,
}
}
sendmessage(msg, sock, trans_id, lock)
end
def find_node(sock, target_id, sender_id, lock, trans_id = nil)
if trans_id == nil then
trans_id = get_trans_id("find_node")
end
msg = {
"y" => "q",
"q" => "find_node",
"a" =>
{
"id" => sender_id,
"target" => target_id
}
}
sendmessage(msg, sock, trans_id, lock)
end
def fond_node(sock, found_nodes, trans_id = nil, sender_id = nil, lock = nil)
msg = {
"y" => "r",
"r" => {
"id" => sender_id,
"nodes" => found_nodes
}
}
sendmessage(msg, sock, trans_id, lock)
end
def get_peers(sock, info_hash, sender_id, lock)
trans_id = get_trans_id("get_peers")
msg = {
"y" => "q",
"q" => "get_peers",
"a" => {"id" => sender_id,
"info_hash" => info_hash
}
}
sendmessage(msg, sock, trans_id, lock)
end
def got_peers(sock, trans_id, sender_id , token, values, nodes, lock)
msg = { "y" => "r",
"r" =>
{"id" => sender_id,
"token" => token
}
}
if values != nil then
msg["values"] = values
else
if nodes != nil then
msg["nodes"] = nodes
end
end
sendmessage(msg, sock, trans_id, lock)
end
def announce_peer(sock, id)
end
def announced_peer(sock, id)
end
end