• 使用Lua的扩展库LuaSocket用例


    目录结构
     
    LuaSocket 是 Lua 的网络模块库,它可以很方便地提供 TCP、UDP、DNS、FTP、HTTP、SMTP、MIME 等多种网络协议的访问操作。
    
    它由两部分组成:一部分是用 C 写的核心,提供对 TCP 和 UDP 传输层的访问支持。另外一部分是用 Lua 写的,负责应用功能的网络接口处理。
    
    一、安装LuaSocket
    
    下面介绍两种安装方法
    
    第一种方法:如果你有安装了 Lua 模块的安装和部署工具 LuaRocks,那么一条指令就能安装部署好 LuaSocket:
    
    # luarocks install luasocket
    第二种方法:如果没安装有 LuaRocks,也可以源码安装。
    
    先把 LuaRocks 下载下来,当前可用的版本是 luasocket-3.0-rc1(luasocket的源码有托管在Github.com):
    
    # git clone https://github.com/diegonehab/luasocket.git
    把源码clone下来之后就可以进行本地源码安装,直接进入到luasocket目录进行编译安装了
    
    # cd luasocket
    # make && make install
    LuaSocket 使用
    
    接下来是LuaSocket扩展的几种使用方法
    
     
    
    1、socket方式请求
    
    -- socket方式请求
    local socket = require("socket")
    local host = "100.42.237.125"
    local file = "/"
    local sock = assert(socket.connect(host, 80))  -- 创建一个 TCP 连接,连接到 HTTP 连接的标准 80 端口上
    sock:send("GET " .. file .. " HTTP/1.0
    
    ")
    repeat
        local chunk, status, partial = sock:receive(1024) -- 以 1K 的字节块来接收数据,并把接收到字节块输出来
        -- print(chunk or partial)
    until status ~= "closed"
    sock:close()  -- 关闭 TCP 连接
    2、HTTP访问请求
    
    -- http访问请求
    http=require("socket.http")
    result=http.request("http://ip.taobao.com/service/getIpInfo.php?ip=123.189.1.100")
    print(result)
    3、SMTP方法发送mail
    
    -- smtp方法发送mail
    local smtp = require("socket.smtp")
    
    from = "<youmail@126.com>" -- 发件人
    
    -- 发送列表
    rcpt = {
        "<youmail@126.com>",
        "<youmail@qq.com>"
    }
    
    mesgt = {
        headers = {
            to = "youmail@gmail.com", -- 收件人
            cc = '<youmail@gmail.com>', -- 抄送
            subject = "This is Mail Title"
        },
        body = "This is  Mail Content."
    }
    
    r, e = smtp.send{
        server="smtp.126.com",
        user="youmail@126.com",
        password="******",
        from = from,
        rcpt = rcpt,
        source = smtp.message(mesgt)
    }
    
    if not r then
       print(e)
    else
       print("send ok!")
    end
    使用 LuaSocket 还算简单吧,直接用 require 函数加载进来就行,在例如下面几个例子
    
    1)输出一个 LuaSocket 版本信息:
    
    local socket = require("socket")
    print(socket._VERSION)
    2)以 socket 的方式访问获取百度首页数据:
    
    local socket = require("socket")
     
    local host = "www.baidu.com"
    local file = "/"
     
    -- 创建一个 TCP 连接,连接到 HTTP 连接的标准端口 -- 80 端口上
    local sock = assert(socket.connect(host, 80))
    sock:send("GET " .. file .. " HTTP/1.0
    
    ")
    repeat
        -- 以 1K 的字节块来接收数据,并把接收到字节块输出来
        local chunk, status, partial = sock:receive(1024)
        print(chunk or partial)
    until status ~= "closed"
    -- 关闭 TCP 连接
    sock:close()
    3)使用模块里内置的 http 方法来访问:
    
    local http = require("socket.http")
    local response = http.request("http://www.baidu.com/")
    print(response)
    一个简单的 client/server 通信连接
    
    本来想写成单 server 多 client 的 socket 聊天服务器,不过最后还是卡在客户端的数据更新上,单进程的 while 轮询(poll),一个 io.read 就把服务器数据接收给截断了。
    
    仅靠现有的 LuaSocket 模块不装其他第三方模块,也是很难做一个实时的聊天,虽然有 soket.select 在苦苦支撑,但是这还是一个填不平的坑来了。
    
    可能用上面向并发的 concurrentlua 模块会解决这个数据接收阻塞问题,这个以后再看看,现阶段的成果是:在客户端的终端上敲一些东西后回车会通过 socket 给服务器发送数据,服务器接收到数据后再返回显示在客户端的终端上。
    
    一个简单的东西,纯属练手,代码如下:
    
    server端
    
    -- server.lua
    local socket = require("socket")
     
    local host = "127.0.0.1"
    local port = "12345"
    local server = assert(socket.bind(host, port, 1024))
    server:settimeout(0)
    local client_tab = {}
    local conn_count = 0
     
    print("Server Start " .. host .. ":" .. port) 
     
    while 1 do
        local conn = server:accept()
        if conn then
            conn_count = conn_count + 1
            client_tab[conn_count] = conn
            print("A client successfully connect!") 
        end
      
        for conn_count, client in pairs(client_tab) do
            local recvt, sendt, status = socket.select({client}, nil, 1)
            if #recvt > 0 then
                local receive, receive_status = client:receive()
                if receive_status ~= "closed" then
                    if receive then
                        assert(client:send("Client " .. conn_count .. " Send : "))
                        assert(client:send(receive .. "
    "))
                        print("Receive Client " .. conn_count .. " : ", receive)   
                    end
                else
                    table.remove(client_tab, conn_count) 
                    client:close() 
                    print("Client " .. conn_count .. " disconnect!") 
                end
            end
             
        end
    end
    client端
    
    -- client.lua
    local socket = require("socket")
     
    local host = "127.0.0.1"
    local port = 12345
    local sock = assert(socket.connect(host, port))
    sock:settimeout(0)
      
    print("Press enter after input something:")
     
    local input, recvt, sendt, status
    while true do
        input = io.read()
        if #input > 0 then
            assert(sock:send(input .. "
    "))
        end
         
        recvt, sendt, status = socket.select({sock}, nil, 1)
        while #recvt > 0 do
            local response, receive_status = sock:receive()
            if receive_status ~= "closed" then
                if response then
                    print(response)
                    recvt, sendt, status = socket.select({sock}, nil, 1)
                end
            else
                break
            end
        end
    end
    转载:D.H.Q的烂笔头
  • 相关阅读:
    【leetcode】1295. Find Numbers with Even Number of Digits
    【leetcode】427. Construct Quad Tree
    【leetcode】1240. Tiling a Rectangle with the Fewest Squares
    【leetcode】1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold
    【leetcode】1291. Sequential Digits
    【leetcode】1290. Convert Binary Number in a Linked List to Integer
    【leetcode】1269. Number of Ways to Stay in the Same Place After Some Steps
    【leetcode】1289. Minimum Falling Path Sum II
    【leetcode】1288. Remove Covered Intervals
    【leetcode】1287. Element Appearing More Than 25% In Sorted Array
  • 原文地址:https://www.cnblogs.com/archoncap/p/5238229.html
Copyright © 2020-2023  润新知