minitcp 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.txt +42 -0
- data/LICENSE +2 -0
- data/README.md +200 -0
- data/Rakefile.rb +217 -0
- data/VERSION +1 -0
- data/lib/minitcp.rb +341 -0
- data/minitcp.gemspec +37 -0
- data/samples/README.md +19 -0
- data/samples/name_server.rb +131 -0
- data/samples/pingpongplot.rb +26 -0
- data/samples/plot.rb +190 -0
- data/samples/proxy.rb +46 -0
- data/samples/relay/README.md +41 -0
- data/samples/relay/c.rb +21 -0
- data/samples/relay/relai_config.data +4 -0
- data/samples/relay/relaiproxy.rb +180 -0
- data/samples/relay.rb +102 -0
- data/samples/spdy.rb +43 -0
- data/samples/statcpu.rb +37 -0
- data/test.rb +192 -0
- metadata +72 -0
data/lib/minitcp.rb
ADDED
@@ -0,0 +1,341 @@
|
|
1
|
+
# LGPL, Author: Regis d'Aubarede <regis.aubarede@gmail.com>
|
2
|
+
#
|
3
|
+
##############################################################
|
4
|
+
# minitcp.rb
|
5
|
+
##############################################################
|
6
|
+
|
7
|
+
require 'thread'
|
8
|
+
require 'timeout'
|
9
|
+
require 'socket'
|
10
|
+
require 'gserver'
|
11
|
+
|
12
|
+
|
13
|
+
module SocketReactive
|
14
|
+
|
15
|
+
def data_readed=(v) @data_readed=v end
|
16
|
+
def data_readed() @data_readed||="" end
|
17
|
+
|
18
|
+
# read n byte, block the caller, return nil if socket if close
|
19
|
+
# if block is defined, it is yield with data, method return whith the value of yield
|
20
|
+
# if looping is true, the method loop until socket close, (or current thread is killed)
|
21
|
+
def receive_n_bytes(sizemax,looping=false,&b)
|
22
|
+
s=sizemax
|
23
|
+
if self.data_readed.size>=sizemax
|
24
|
+
buff,self.data_readed=self.data_readed[0..sizemax-1],self.data_readed[sizemax..-1]
|
25
|
+
buff=b.call(buff) if block_given?
|
26
|
+
return buff unless looping
|
27
|
+
end
|
28
|
+
s=sizemax-self.data_readed.size
|
29
|
+
loop do
|
30
|
+
#p ["waiting ",s,data_readed]
|
31
|
+
sd=s>1024 ? 1024 : s
|
32
|
+
data=(self.recv(sd) rescue nil)
|
33
|
+
#p "nrec: w#{sizemax}/ rec:#{(data||'').size} / #{sd} old=#{data_readed.size} /// #{(data||'').size<70 ? data : "."}"
|
34
|
+
if data && data.size>0
|
35
|
+
self.data_readed=self.data_readed+data
|
36
|
+
s=sizemax-self.data_readed.size
|
37
|
+
if s<=0
|
38
|
+
buff,self.data_readed=self.data_readed,""
|
39
|
+
s=sizemax
|
40
|
+
buff=b.call(buff) if block_given?
|
41
|
+
return buff unless looping
|
42
|
+
end
|
43
|
+
else
|
44
|
+
close rescue nil
|
45
|
+
break # socket close
|
46
|
+
end
|
47
|
+
end #loop
|
48
|
+
end
|
49
|
+
# wait n byte or timeout. if block is defined, it is yielded with data
|
50
|
+
# return nil if timeout/socket closed, or data if no bloc, or yield value
|
51
|
+
def received_n_timeout(sizemax,timeout_ms,&b)
|
52
|
+
timeout(timeout_ms/1000.0) {
|
53
|
+
ret=receive_n_bytes(sizemax,false,&b)
|
54
|
+
return ret
|
55
|
+
}
|
56
|
+
rescue Timeout::Error
|
57
|
+
return nil
|
58
|
+
rescue Exception => e
|
59
|
+
$stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def received_any_timeout(sizemax,timeout_ms)
|
63
|
+
timeout(timeout_ms/1000.0) {
|
64
|
+
return recv(sizemax)
|
65
|
+
}
|
66
|
+
rescue Timeout::Error
|
67
|
+
return nil
|
68
|
+
rescue Exception => e
|
69
|
+
$stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}"
|
70
|
+
end
|
71
|
+
|
72
|
+
# async wait and read data on socket, yield values readed,
|
73
|
+
# return thread spawned, which can be kill
|
74
|
+
def on_any_receive()
|
75
|
+
Thread.new() do
|
76
|
+
begin
|
77
|
+
if self.data_readed.size>0
|
78
|
+
buff,self.data_readed=self.data_readed,""
|
79
|
+
yield(buff)
|
80
|
+
end
|
81
|
+
loop do
|
82
|
+
data=(self.recv(64*1024) rescue nil)
|
83
|
+
data && data.size>0 ? yield(data) : break
|
84
|
+
end
|
85
|
+
rescue Exception => e
|
86
|
+
$stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}"
|
87
|
+
end
|
88
|
+
close rescue nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# async yield on received n bytes
|
94
|
+
# return thread spawned, which can be kill
|
95
|
+
def on_n_receive(sizemax=1,&b)
|
96
|
+
Thread.new() do
|
97
|
+
begin
|
98
|
+
receive_n_bytes(sizemax,true,&b)
|
99
|
+
rescue Exception => e
|
100
|
+
$stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# read until separator reached, block the caller, return nil if socket is close
|
106
|
+
# if block is defined, it is yield with data, method return whith the value of yield
|
107
|
+
# if looping is true, the method loop until socket close, (or current thread is killed)
|
108
|
+
# this read some extra data. they can be retrieve with in socket.data_readed.
|
109
|
+
# data_readed is use for next calls to receives_n_byte/receive_sep
|
110
|
+
def receive_sep(separator,sizemax=1024,looping=false,&b)
|
111
|
+
if self.data_readed.size>0
|
112
|
+
a=self.data_readed.split(separator,2)
|
113
|
+
while a.size>1
|
114
|
+
buff= a.size>2 ? a[0..-2] : a.first
|
115
|
+
self.data_readed=a.last
|
116
|
+
buff=b.call(buff) if block_given?
|
117
|
+
return buff unless looping
|
118
|
+
a=self.data_readed.split(separator,2)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
loop do
|
122
|
+
data=(self.recv(sizemax-self.data_readed.size) rescue nil)
|
123
|
+
if data && data.size>0
|
124
|
+
self.data_readed=self.data_readed+data
|
125
|
+
a=(self.data_readed).split(separator,2)
|
126
|
+
while a.size>1
|
127
|
+
buff= a.size>2 ? a[0..-2] : a.first
|
128
|
+
self.data_readed=a.last
|
129
|
+
buff=b.call(buff) if block_given?
|
130
|
+
return buff unless looping
|
131
|
+
a=(self.data_readed).split(separator,2)
|
132
|
+
end
|
133
|
+
else
|
134
|
+
close rescue nil
|
135
|
+
break
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# async yield on received data until end-buffer string
|
141
|
+
# end-buffer can be string or regexp (args of data.split(,2))
|
142
|
+
# return thread spawned, which can be kill
|
143
|
+
# this read some extra data. they can be retrieve with in socket.data_readed.
|
144
|
+
# data_readed is use for next calls to receives_n_byte/receive_sep
|
145
|
+
def on_receive_sep(separator,sizemax=1024,&b)
|
146
|
+
Thread.new() do
|
147
|
+
begin
|
148
|
+
receive_sep(separator,sizemax,looping=true,&b)
|
149
|
+
rescue Exception => e
|
150
|
+
$stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# async yield after a duration, if socket is open
|
156
|
+
# return thread spawned, which can be kill
|
157
|
+
def after(duration_ms)
|
158
|
+
Thread.new() do
|
159
|
+
begin
|
160
|
+
sleep(duration_ms/1000.0)
|
161
|
+
yield unless self.connected?()
|
162
|
+
rescue Exception => e
|
163
|
+
$stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# async yield periodicaly, if socket is open
|
169
|
+
# return thread spawned, which can be kill
|
170
|
+
def on_timer(value=1000)
|
171
|
+
Thread.new() {
|
172
|
+
begin
|
173
|
+
nbtick=(value/TICK)+1
|
174
|
+
loop do
|
175
|
+
i=0
|
176
|
+
sleep(TICK/1000.0) while self.connected?() && (i+=1)<nbtick
|
177
|
+
self.connected?() ? yield() : break
|
178
|
+
end
|
179
|
+
rescue Exception => e
|
180
|
+
$stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}"
|
181
|
+
end
|
182
|
+
}
|
183
|
+
end
|
184
|
+
|
185
|
+
# wait until curent socket is close.
|
186
|
+
def wait_end()
|
187
|
+
begin
|
188
|
+
loop do
|
189
|
+
sleep(TICK/1000.0) while (self.connected?() rescue nil)
|
190
|
+
break
|
191
|
+
end
|
192
|
+
rescue Exception => e
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# Test if a socket is open. (use socket.remote_address() !)
|
197
|
+
def connected?()
|
198
|
+
(self.remote_address rescue nil) ? true : false
|
199
|
+
end
|
200
|
+
# duration of sleep when active wait (wait_end,on_timer...)
|
201
|
+
TICK=600
|
202
|
+
|
203
|
+
def self.make_socket_reactive(socket)
|
204
|
+
socket.extend(SocketReactive)
|
205
|
+
socket.data_readed=""
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# Assure connection to server, extend socket connection by SocketReactive module.
|
210
|
+
#
|
211
|
+
# MClient.run_one_shot("localhost",2200) do |socket| .. end.join
|
212
|
+
#
|
213
|
+
# MClient.run_continous("localhost",2200,6000) do |socket| .. end.join
|
214
|
+
#
|
215
|
+
class MClient
|
216
|
+
# maintain a conntection to a TCP serveur, sleep timer_interconnection_ms millisecondes
|
217
|
+
# beetwen each reconnections
|
218
|
+
def self.run_continious(host,port,timer_interconnection_ms,&b)
|
219
|
+
Thread.new do
|
220
|
+
loop { run_one_shot(host,port,&b).join ; sleep timer_interconnection_ms/1000.0 }
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def self.run_continous(host,port,timer_interconnection,&b)
|
225
|
+
self.run_continious(host,port,timer_interconnection,&b)
|
226
|
+
end
|
227
|
+
|
228
|
+
# Connecte to a TCP server, call block with client socket if connection sucess.
|
229
|
+
# enssure close connection after end of block
|
230
|
+
def self.run_one_shot(host="localhost",port=80)
|
231
|
+
begin
|
232
|
+
sleep(0.03) # give some time for server ready (for test...)
|
233
|
+
socket = TCPSocket.new(host,port)
|
234
|
+
rescue
|
235
|
+
puts "not connected to #{host}:#{port}: " + $!.to_s
|
236
|
+
return (Thread.new {})
|
237
|
+
end
|
238
|
+
SocketReactive::make_socket_reactive(socket)
|
239
|
+
Thread.new do
|
240
|
+
begin
|
241
|
+
yield(socket)
|
242
|
+
rescue Exception => e
|
243
|
+
puts "#{e}\n #{e.backtrace.join("\n ")}"
|
244
|
+
ensure
|
245
|
+
socket.close() rescue nil
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
|
252
|
+
# Assure connection to server, extend socket connection by SocketReactive module.
|
253
|
+
#
|
254
|
+
# MClient.run_one_shot("localhost",2200) do |socket| .. end.join
|
255
|
+
#
|
256
|
+
# MClient.run_continous("localhost",2200,6000) do |socket| .. end.join
|
257
|
+
#
|
258
|
+
class UDPAgent
|
259
|
+
# maintain a conntection to a TCP serveur, sleep timer_interconnection_ms millisecondes
|
260
|
+
# beetwen each reconnections
|
261
|
+
def self.send_datagram(host,port,mess)
|
262
|
+
sock = UDPSocket.new
|
263
|
+
#p ["sock.send",mess, 0, host, port]
|
264
|
+
sock.send(mess, 0, host, port)
|
265
|
+
sock.close
|
266
|
+
end
|
267
|
+
def self.send_datagram_on_socket(socket,host,port,mess)
|
268
|
+
socket.send(mess, 0, host, port)
|
269
|
+
end
|
270
|
+
|
271
|
+
Thread.abort_on_exception=true
|
272
|
+
|
273
|
+
# send datagram on timer
|
274
|
+
def self.on_timer(periode,options)
|
275
|
+
Thread.new do
|
276
|
+
sleep periode/1000.0
|
277
|
+
sock = UDPSocket.new
|
278
|
+
if options[:port]
|
279
|
+
sock.bind("0.0.0.0", options[:port])
|
280
|
+
end
|
281
|
+
loop do
|
282
|
+
rep=IO.select([sock],nil,nil,periode/1000.0)
|
283
|
+
#puts "IO.SELECT => #{rep}"
|
284
|
+
if rep
|
285
|
+
Thread.new {
|
286
|
+
data,peer=sock.recvfrom(1024)
|
287
|
+
options[:on_receive].call(data,peer,sock)
|
288
|
+
} if options[:on_receive]
|
289
|
+
elsif options[:on_timer]
|
290
|
+
h=options[:on_timer].call()
|
291
|
+
self.send_datagram_on_socket(sock,h[:host], h[:port],h[:mess]) if h && h[:mess] && h[:host] && h[:port]
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
# recieved UDP datagramme, bloc can ellaborate a reply, which will be sending to client
|
297
|
+
def self.on_datagramme(host,port)
|
298
|
+
serv = UDPSocket.new
|
299
|
+
serv.bind(host, port)
|
300
|
+
Thread.new do
|
301
|
+
loop do
|
302
|
+
begin
|
303
|
+
Thread.new(*serv.recvfrom(1024)) do |data,peer| # peer=["AF_INET", 59340, "127.0.0.1", "127.0.0.1"]
|
304
|
+
proto,cli_port,srv_addr,cli_addr=*peer
|
305
|
+
response=yield(data,cli_addr,cli_port)
|
306
|
+
self.send_datagram_on_socket(serv,cli_addr,cli_port,response) if response
|
307
|
+
end
|
308
|
+
rescue Exception => e
|
309
|
+
puts "#{e}\n #{e.backtrace.join("\n ")}"
|
310
|
+
ensure
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# Run a TCP serveur, with a max connection simultaneous,
|
318
|
+
# When connection succes, call the bloc given with socket (extended by SocketReactive).
|
319
|
+
#
|
320
|
+
# MServer( "8080" , "0.0.0.0" ,1) { |socket| loop { p socket.gets} }
|
321
|
+
class MServer < GServer
|
322
|
+
def self.service(port,host,max,&b)
|
323
|
+
srv=new(port,host,max,&b)
|
324
|
+
srv.audit = true
|
325
|
+
srv.start
|
326
|
+
srv
|
327
|
+
end
|
328
|
+
def initialize(port,host,max=1,&b)
|
329
|
+
super(port,host,max)
|
330
|
+
@bloc=b
|
331
|
+
end
|
332
|
+
def serve( io )
|
333
|
+
SocketReactive::make_socket_reactive(io)
|
334
|
+
begin
|
335
|
+
@bloc.call(io)
|
336
|
+
rescue Exception => e
|
337
|
+
puts "Error in Mserver block: #{e} :\n #{e.backtrace.join("\n ")}"
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
data/minitcp.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push('lib')
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "minitcp"
|
6
|
+
s.licenses = ['LGPL']
|
7
|
+
s.version = File.read("VERSION").strip
|
8
|
+
s.date = Time.now.to_s.split(/\s+/)[0]
|
9
|
+
s.email = "regis.aubarede@gmail.com"
|
10
|
+
s.homepage = "https://github.com/glurp/minitcp"
|
11
|
+
s.authors = ["Regis d'Aubarede"]
|
12
|
+
s.summary = "A DSL for programming little Tcp client and server"
|
13
|
+
s.description = <<EEND
|
14
|
+
A DSL for programming little Tcp client and server
|
15
|
+
EEND
|
16
|
+
|
17
|
+
dependencies = [
|
18
|
+
]
|
19
|
+
|
20
|
+
s.files = Dir['**/*'].reject { |a| a =~ /^\.git/ || a =~ /\._$/ || a =~ /\.~$/}
|
21
|
+
s.test_files = Dir['samples/**']
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
|
24
|
+
## Make sure you can build the gem on older versions of RubyGems too:
|
25
|
+
s.rubygems_version = "1.8.15"
|
26
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
27
|
+
s.specification_version = 3 if s.respond_to? :specification_version
|
28
|
+
|
29
|
+
dependencies.each do |type, name, version|
|
30
|
+
if s.respond_to?("add_#{type}_dependency")
|
31
|
+
s.send("add_#{type}_dependency", name, version)
|
32
|
+
else
|
33
|
+
s.add_dependency(name, version)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
data/samples/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Minitcp usages
|
2
|
+
===
|
3
|
+
|
4
|
+
**proxy.rb** : real tcp proxy
|
5
|
+
|
6
|
+
**name_server.rb** : my dns service :)
|
7
|
+
|
8
|
+
**relay.rb** : not ready , tcp relay for bypass firewall/proxy protection
|
9
|
+
|
10
|
+
*spdy.rb** : SPDY server relay for http server
|
11
|
+
|
12
|
+
Dynamic ploting
|
13
|
+
===
|
14
|
+
|
15
|
+
**plot.rb** : realy no tcp... , plot measures on stdin to screen
|
16
|
+
|
17
|
+
**pingpongplot.rb** : measure connection time to google.com (for piping to plot.rb)
|
18
|
+
|
19
|
+
**statcpu.rb** : linux : cpu time to stdout, for piping to plot.rb
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# LGPL, Author: Regis d'Aubarede <regis.aubarede@gmail.com>
|
2
|
+
#################################################################
|
3
|
+
# name_server.rb
|
4
|
+
#################################################################
|
5
|
+
require_relative '../lib/minitcp.rb'
|
6
|
+
|
7
|
+
BasicSocket.do_not_reverse_lookup = true
|
8
|
+
Thread.abort_on_exception = true
|
9
|
+
|
10
|
+
$SIZE=30
|
11
|
+
$dico_name={}
|
12
|
+
$dico_ip={}
|
13
|
+
|
14
|
+
def run_net_relay()
|
15
|
+
MServer.service(4410,"0.0.0.0",1000) do |socket|
|
16
|
+
socket.on_n_receive($SIZE) do |data|
|
17
|
+
ip=socket.remote_address.ip_address
|
18
|
+
cmd,url,http=data.split(' ')
|
19
|
+
name,method,*args=url.split('/').last
|
20
|
+
next if cmd!="GET"
|
21
|
+
case method
|
22
|
+
when "server"
|
23
|
+
old=ActiveConnection.search(name)
|
24
|
+
if old && old.state==:free
|
25
|
+
old.deconnect
|
26
|
+
old=nil
|
27
|
+
end
|
28
|
+
if !old || old.state==:connected
|
29
|
+
ActiveConnection.add(socket)
|
30
|
+
end
|
31
|
+
when "client"
|
32
|
+
if srv=ActiveConnection.search(args.first)
|
33
|
+
srv.connect_to(name)
|
34
|
+
else
|
35
|
+
smess("NOTCONNECT")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
rep=""
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def smess(socket,*args)
|
44
|
+
data= args.join(";")+";"
|
45
|
+
socket.send(data+" "*($SIZE-data.length),0) rescue p $!
|
46
|
+
end
|
47
|
+
|
48
|
+
def run_server_name()
|
49
|
+
MServer.service(4400,"0.0.0.0",100) do |socket|
|
50
|
+
socket.on_n_receive($SIZE) do |data|
|
51
|
+
ip=socket.remote_address.ip_address
|
52
|
+
cmd,*args=data.split(";")
|
53
|
+
name=args.first
|
54
|
+
rep=""
|
55
|
+
case cmd
|
56
|
+
when "update"
|
57
|
+
$dico_name[name]=ip
|
58
|
+
$dico_ip[ip]=name
|
59
|
+
rep="OK"
|
60
|
+
when "forget"
|
61
|
+
oldip=$dico_ip[ip]
|
62
|
+
if oldip && $dico_ip[ip]==name && $dico_name[name]==ip
|
63
|
+
$dico_name.delete(name)
|
64
|
+
$dico_ip.delete(ip)
|
65
|
+
rep="OK"
|
66
|
+
end
|
67
|
+
when "get"
|
68
|
+
rep=$dico_name[name].to_s
|
69
|
+
when "geti"
|
70
|
+
rep=$dico_ip[name].to_s
|
71
|
+
end
|
72
|
+
rep.size>0 ? smess(socket,"ACK",name,rep) : smess(socket,"NACK","NOK","NOK")
|
73
|
+
end
|
74
|
+
socket.after(10*1000) { socket.close rescue nil}
|
75
|
+
socket.wait_end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
################# Client api ########################
|
80
|
+
|
81
|
+
def update_server_name(hostname)
|
82
|
+
MClient.run_one_shot("localhost",4400) do |socket|
|
83
|
+
socket.on_n_receive($SIZE) { |data| p data ; socket.close }
|
84
|
+
smess(socket,"update",hostname)
|
85
|
+
socket.wait_end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
def fetch_name(hostname)
|
89
|
+
ret=""
|
90
|
+
MClient.run_one_shot("localhost",4400) do |socket|
|
91
|
+
socket.on_n_receive($SIZE) { |data| ret= data.split(";")[2] ; socket.close }
|
92
|
+
smess(socket,"get",hostname)
|
93
|
+
socket.wait_end
|
94
|
+
ret
|
95
|
+
end.join
|
96
|
+
ret
|
97
|
+
end
|
98
|
+
def fetch_ip(ip)
|
99
|
+
ret=""
|
100
|
+
MClient.run_one_shot("localhost",4400) do |socket|
|
101
|
+
socket.on_n_receive($SIZE) { |data| ret= data.split(";")[2] ; socket.close }
|
102
|
+
smess(socket,"geti",ip)
|
103
|
+
socket.wait_end
|
104
|
+
ret
|
105
|
+
end.join
|
106
|
+
ret
|
107
|
+
end
|
108
|
+
def forget_me(name)
|
109
|
+
MClient.run_one_shot("localhost",4400) do |socket|
|
110
|
+
ret="?"
|
111
|
+
socket.on_n_receive($SIZE) { |data| ret= data.split(";")[2] ; socket.close }
|
112
|
+
smess(socket,"forget",name)
|
113
|
+
socket.wait_end
|
114
|
+
p "forget : #{ret}"
|
115
|
+
end.join
|
116
|
+
end
|
117
|
+
|
118
|
+
if $0==__FILE__
|
119
|
+
run_server_name
|
120
|
+
|
121
|
+
Thread.new { 4.times { update_server_name("glurp") ; sleep 1 } }
|
122
|
+
Thread.new { 4.times { update_server_name("glurp22") ; sleep 1 } }
|
123
|
+
|
124
|
+
sleep 2
|
125
|
+
puts "\n\n***************** get name *******************\n\n"
|
126
|
+
|
127
|
+
p fetch_name("glurp")
|
128
|
+
p fetch_ip("127.0.0.1")
|
129
|
+
forget_me("glurp22")
|
130
|
+
sleep
|
131
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# LGPL, Author: Regis d'Aubarede <regis.aubarede@gmail.com>
|
2
|
+
#################################################################
|
3
|
+
# pingpongplot.rb : measure pingpong time on google, plot it
|
4
|
+
#
|
5
|
+
# Usage :
|
6
|
+
# > ruby pingpongplot.rb | ruby plot.rb 0 0 300 pingpong auto
|
7
|
+
#################################################################
|
8
|
+
require_relative '../lib/minitcp.rb'
|
9
|
+
|
10
|
+
|
11
|
+
$stdout.sync=true
|
12
|
+
|
13
|
+
MClient.run_continious("google.com",80,100) do |socket|
|
14
|
+
s=Time.now.to_f
|
15
|
+
socket.on_receive_sep("\r\n") do |data|
|
16
|
+
$stdout.puts("#{(Time.now.to_f-s)*1000}")
|
17
|
+
socket.close rescue nil
|
18
|
+
Thread.current.kill
|
19
|
+
end
|
20
|
+
s=Time.now.to_f
|
21
|
+
socket.print "GET /blabla HTTP/1.0\r\n\r\n"
|
22
|
+
socket.wait_end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
sleep
|