-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathex26.1.lua
More file actions
80 lines (71 loc) · 1.83 KB
/
ex26.1.lua
File metadata and controls
80 lines (71 loc) · 1.83 KB
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
local socket = require "socket"
local function receive (connection)
connection:settimeout(0)
-- do not block
local s, status, partial = connection:receive(2^10)
if status == "timeout" then
coroutine.yield(connection)
end
return s or partial, status
end
local function download (host, file)
local c = assert(socket.connect(host, 80))
local count = 0 -- counts number of bytes read
local request = string.format(
"GET %s HTTP/1.0\r\nhost: %s\r\n\r\n", file, host)
c:send(request)
while true do
local s, status = receive(c)
count = count + #s
if status == "closed" then break end
end
c:close()
print(file, count)
end
local tasks = {} -- list of all live tasks
local function get (host, file)
-- create coroutine for a task
local co = coroutine.wrap(function ()
download(host, file)
end)
-- insert it in the list
table.insert(tasks, co)
end
local function dispatch ()
local i = 1
local timedout = {}
while true do
if tasks[i] == nil then
-- no other tasks?
if tasks[1] == nil then
-- list is empty?
break
-- break the loop
end
i = 1
-- else restart the loop
timedout = {}
end
local res = tasks[i]()
-- run a task
if not res then
-- task finished?
table.remove(tasks, i)
else
-- time out
i = i + 1
timedout[#timedout + 1] = res
if #timedout == #tasks then
-- all tasks blocked?
socket.select(timedout)
-- wait
end
end
end
end
get("www.lua.org", "/ftp/lua-5.3.1.tar.gz")
-- get("www.lua.org", "/ftp/lua-5.3.0.tar.gz")
-- get("www.lua.org", "/ftp/lua-5.2.4.tar.gz")
-- get("www.lua.org", "/ftp/lua-5.2.3.tar.gz")
-- get("www.lua.org", "/ftp/lua-5.3.2.tar.gz")
dispatch()