這是一個簡單的文件傳輸例子,使用了skynet封裝的socket接口。熟悉一個框架最好的方法就是用它。
skynet有一個“服務(service)”的概念,每個服務類似與一個模塊,完成特定的任務,啓動一個服務可以使用 newservice() 或 uniqueservice()。
首先是客戶端:
package.cpath = "luaclib/?.so"
package.path = "lualib/?.lua;examples/?.lua"
local socket = require "clientsocket"
local host = "127.0.0.1"
local port = 8888
local path = "/home/mick/"
local filename = "cxl"
local blocksize = 2
local socket_fd = socket.connect(host, port)
print(path .. filename)
local file = io.open(path .. filename, "rb")
local len = file:seek("end")
file:seek("set")
local time
local remain
time = math.modf(len / blocksize) + 1
remain = len % blocksize
socket.send(socket_fd, filename .. "\n")
socket.send(socket_fd, tostring(len) .. "\n")
while time > 0 do
if time > 1 then
time = time - 1
socket.send(socket_fd, file:read(blocksize))
else
time = time - 1
socket.send(socket_fd, file:read(remain))
end
end
io.close(file)
socket.close(socket_fd)
客戶端使用了 "clientsocket" 中封裝的c接口,最上面兩行代碼分別是 c 庫和 lua 庫地址。代碼參考自 examples/client.lua ,裏面有 "clientsocket" 的使用例子。爲了將文件傳輸到服務器,文件的傳輸分三個步驟:
1、傳輸文件名;
2、傳輸文件大小;
3、傳輸文件內容。
爲了方便服務器識別這三個步驟,對於前兩個步驟,服務器端都使用了 readline() 函數,該函數可以以給定的分隔符爲接收數據的結束標誌,默認以換行符爲分隔符。這裏我們就使用 '\n'(換行符) 爲分隔符,可以發現在發送數據時我們專門在數據末尾添加了換行符,接收端的readline() 函數以換行符爲接收結束符,但不會存儲換行符。文件的傳輸過程,每次按固定大小發送數據,最後一次補全剩餘即可。
服務器端:
./examples/server.lua
local skynet = require "skynet"
local socket = require "socket"
local path = "/home/mick/"
local filename = ""
local function accept(fd, addr)
print(fd, addr)
socket.start(fd)
local data = socket.readline(fd)
local len = socket.readline(fd)
len = tonumber(len)
print(data, len, type(len))
filename = data .. "_copy"
local file = io.open(path .. filename, "wb")
while len > 0 do
data = socket.readall(fd)
file:write(data)
len = len - #data
print(len)
end
io.close(file)
socket.close(fd)
end
skynet.start(function()
local address = "0.0.0.0"
local port = 8888
socket_listen = socket.listen(address, port)
socket.start(socket_listen, accept)
end)
服務器端的socket的API詳解見官方文檔:https://github.com/cloudwu/skynet/wiki/Socket
此外,服務器端還需要啓動該服務:
local skynet = require "skynet"
local max_client = 64
skynet.start(function()
skynet.error("Server start")
local server = skynet.newservice("server")
skynet.exit()
end)