functiondownload(host,file) local c = assert(socket.connect(host,80)) local count = 0 local request = string.format("GET %s HTTP/1.0\r\nhost:%s\r\n\r\n",file,host) c:send(request) whiletruedo local s ,status = receive(c) count = count + #s ifstatus == "closed"thenbreakend end c:close() print(file,count) end
functionreceive(connection) local s,status,partial = connection:receive(2^10) return s or partial,status end
在并行的实现中,这个函数在接收数据时不能阻塞。因此,在没有足够的可用数据时,该函数会挂起,如下:
1 2 3 4 5 6 7 8
functionreceive(connection) connection:settimeout(0) --不阻塞 local s ,status,partial = connection:receive(2^10) ifstatus == "timeout"then coroutine.yield(connection) end return s or partial,status end
tasks = {} -- 所有活跃任务的列表 functionget(host,file) local co = coroutine.wrap(function() download(host,file) end) table.insert(tasks,co) end
functiondispatch() local i = 1 whiletruedo if tasks[i] == nilthen if tasks[1] == nilthen break end i = 1 end local res = tasks[i]() ifnot res then table.remove(tasks,i) else i = i + 1 end end end
functiondispatch() local i = 1 local timedout = {} whiletruedo if tasks[i] == nilthen if tasks[1] == nilthen break end i = 1 timedout ={} end local res = tasks[i]() ifnot res then table.remove(tasks,i) else i = i + 1 timeout[#timedout + 1] = res if #timedout == #tasks then socket.select(timedout) end end end end