首页 > 代码库 > mac下安装LuaSocket

mac下安装LuaSocket

安装LuaSocket

LuaSocket 是 Lua 的网络模块库,它可以很方便地提供 TCP、UDP、DNS、FTP、HTTP、SMTP、MIME 等多种网络协议的访问操作。它由两部分组成:一部分是用 C 写的核心,提供对 TCP 和 UDP 传输层的访问支持。另外一部分是用 Lua 写的,负责应用功能的网络接口处理。

安装LuaSocket

  • Homebrew安装(如果已经安装略过此步)

首先你要安装Homebrew。安装 Homebrew 很简单,只需在终端上输入一行 Ruby 脚本(所以要先搭建 Ruby 运行环境,Mac 下已经预装了 Ruby)就行:

  1. ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
  • LuaRocks安装 (如果已经安装略过此步)

Mac 下的 Homebrew 居然内置了 LuaRocks 的安装包(之前安装 Lua,用 “brew search lua” 搜 Lua 安装包时无意间发现),因此,在 Mac 下安装 LuaRocks 很简单,一条指令就行:

  1. brew install luarocks -v
  • LuaSocket安装

如果你安装有 Lua 模块的安装和部署工具 – LuaRocks,那么一条指令就能安装部署好 LuaSocket:

  1. luarocks install luasocket

LuaSocket 使用

使用 LuaSocket 很简单,直接用 require 函数加载进来就行,例如输出一个 LuaSocket 版本信息:

  1. local socket = require("socket")
  2. print(socket._VERSION)

模块 LuaSocket 内置的常量、函数的结构图如下:

  1. - sleep [function: 0x7feeeb40f940]
  2. - source [function: 0x7feeeb413570]
  3. - newtry [function: 0x7feeeb40f8c0]
  4. - _VERSION [LuaSocket 2.0.2]
  5. - connect [function: 0x7feeeb4122f0]
  6. - sink [function: 0x7feeeb410ea0]
  7. - __unload [function: 0x7feeeb4107e0]
  8. - bind [function: 0x7feeeb413380]
  9. - _M {.}
  10. - _DEBUG [true]
  11. - skip [function: 0x7feeeb4107b0]
  12. - dns - gethostname [function: 0x7feeeb410af0]
  13. | - tohostname [function: 0x7feeeb410b20]
  14. | - toip [function: 0x7feeeb410aa0]
  15. - gettime [function: 0x7feeeb40f8f0]
  16. - select [function: 0x7feeeb412290]
  17. - BLOCKSIZE [2048]
  18. - sinkt - default [function: 0x7feeeb410e20]
  19. | - close-when-done [function: 0x7feeeb410dc0]
  20. | - keep-open [function: 0x7feeeb410e20]
  21. - sourcet - by-length [function: 0x7feeeb410e50]
  22. | - default [function: 0x7feeeb413440]
  23. | - until-closed [function: 0x7feeeb413440]
  24. - tcp [function: 0x7feeeb412020]
  25. - _NAME [socket]
  26. - choose [function: 0x7feeeb410ce0]
  27. - try [function: 0x7feeeb410ca0]
  28. - protect [function: 0x7feeeb410760]
  29. - _PACKAGE []
  30. - udp [function: 0x7feeeb410fd0]

以 socket 的方式访问获取度娘首页数据:

  1. local socket = require("socket")
  2. local host = "www.baidu.com"
  3. local file = "/"
  4. -- 创建一个 TCP 连接,连接到 HTTP 连接的标准端口 -- 80 端口上
  5. local sock = assert(socket.connect(host, 80))
  6. sock:send("GET " .. file .. " HTTP/1.0\r\n\r\n")
  7. repeat
  8. -- 1K 的字节块来接收数据,并把接收到字节块输出来
  9. local chunk, status, partial = sock:receive(1024)
  10. print(chunk or partial)
  11. until status ~= "closed"
  12. -- 关闭 TCP 连接
  13. sock:close()

或者使用模块里内置的 http 方法来访问:

  1. local http = require("socket.http")
  2. local response = http.request("http://www.baidu.com/")
  3. print(response)

以下是一个简单的http方法的例子,用于某学校的网络连接。

  1. local http=require("socket.http");
  2. local request_body = [[username=21451141&password=...]]
  3. local response_body = {}
  4. local res, code, response_headers = http.request{
  5. url = "http://192.0.0.6/cgi-bin/do_login",
  6. method = "POST",
  7. headers =
  8. {
  9. ["Content-Type"] = "application/x-www-form-urlencoded";
  10. ["Content-Length"] = #request_body;
  11. },
  12. source = ltn12.source.string(request_body),
  13. sink = ltn12.sink.table(response_body),
  14. }
  15. print(res)
  16. print(code)
  17. if type(response_headers) == "table" then
  18. for k, v in pairs(response_headers) do
  19. print(k, v)
  20. end
  21. end
  22. print("Response body:")
  23. if type(response_body) == "table" then
  24. print(table.concat(response_body))
  25. else
  26. print("Not a table:", type(response_body))
  27. end

一个简单的 client/server 通信连接

在客户端的终端上敲一些东西后回车会通过 socket 给服务器发送数据,服务器接收到数据后再返回显示在客户端的终端上。一个简单的东西,纯属练手,代码如下:

  1. -- server.lua
  2. local socket = require("socket")
  3. local host = "127.0.0.1"
  4. local port = "12345"
  5. local server = assert(socket.bind(host, port, 1024))
  6. server:settimeout(0)
  7. local client_tab = {}
  8. local conn_count = 0
  9. print("Server Start " .. host .. ":" .. port)
  10. while 1 do
  11. local conn = server:accept()
  12. if conn then
  13. conn_count = conn_count + 1
  14. client_tab[conn_count] = conn
  15. print("A client successfully connect!")
  16. end
  17. for conn_count, client in pairs(client_tab) do
  18. local recvt, sendt, status = socket.select({client}, nil, 1)
  19. if #recvt > 0 then
  20. local receive, receive_status = client:receive()
  21. if receive_status ~= "closed" then
  22. if receive then
  23. assert(client:send("Client " .. conn_count .. " Send : "))
  24. assert(client:send(receive .. "\n"))
  25. print("Receive Client " .. conn_count .. " : ", receive)
  26. end
  27. else
  28. table.remove(client_tab, conn_count)
  29. client:close()
  30. print("Client " .. conn_count .. " disconnect!")
  31. end
  32. end
  33. end
  34. end
  1. -- client.lua
  2. local socket = require("socket")
  3. local host = "127.0.0.1"
  4. local port = 12345
  5. local sock = assert(socket.connect(host, port))
  6. sock:settimeout(0)
  7. print("Press enter after input something:")
  8. local input, recvt, sendt, status
  9. while true do
  10. input = io.read()
  11. if #input > 0 then
  12. assert(sock:send(input .. "\n"))
  13. end
  14. recvt, sendt, status = socket.select({sock}, nil, 1)
  15. while #recvt > 0 do
  16. local response, receive_status = sock:receive()
  17. if receive_status ~= "closed" then
  18. if response then
  19. print(response)
  20. recvt, sendt, status = socket.select({sock}, nil, 1)
  21. end
  22. else
  23. break
  24. end
  25. end
  26. end

感谢D.H.Q的烂笔头

mac下安装LuaSocket