您的位置:首页 > 其它

【Skynet】使用skynet在服务器与客户端间传输文件

2017-09-18 10:27 295 查看
这是一个简单的文件传输例子,使用了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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: