简介
使用lua进行tcp网络编程,最先想到的就是使用luasocket扩展模块,使用luarocks安装完luasocket后,接下来就是研究怎么使用的问题了。
导入socket
local socket = require("socket")
连接服务
local clisock = socket.tcp()
local host = host or '127.0.0.1'
local port = '8888'
local clicon = clisock:connect(host,port)
clisock:settimeout(0)
此处,settimeout(0)表示要客户端采用非阻塞方式通信。
为什么要采用非阻塞通信?
根据文档和个人实验,receive目前只接受三种类型的参数
*a
接收socket中的全部数据,直至socket关闭,如果socket不关闭,好像receive函数会阻塞在那里,始终无法返回。
rbuf, err = clisock:receive('*a')
个人感觉只有对端服务主动关闭连接时,这个函数才返回,并把结果保存在
rbuf中(难道是专为短连接准备的?)。
*l
接收一行数据,也就是receive函数在遇到换行符时才返回,并把接收到
的结果放在第一个返回值中,第二个返回值为错误结果。如果receive没有
任何参数,则默认就是接收一行数据。
rbuf, err = clisock:receive('*l')
rbuf, err = clisock:receive()
上面2行是一个意思,就是接收一行数据。
一个正整数作为参数
接收指定长度(单位:字节)的数据才返回,并把结果保存在第一个返回
值中。
那有的同学就要问了,如果服务器返回的数据长度始终小于指定长度怎么办?
此时,settimeout(0)就发挥作用了,如果接收的数据长度始终小于指定长
度,receive会按照超时返回(不会阻塞),此时返回的数据保存在receive
函数的第三个返回值中。
rbuf, err, partial = clisock:receive(1024)
上述代码中,预期接收1024个字节的数据,超时设置为0。
有以下3种返回结果:
rbuf | err | partial | |
---|---|---|---|
nil | ‘timeout’ | string | 未接收到1024字节就超时了, 在partial中 |
string | nil | nil | 在超时前就接收到1024字节数据,在rbuf中 |
nil | ‘timeout’ | nil | 超时,没有接收到任何数据 |
是否还有其它情况,不得而知。
总结
使用luasocket receive接收二进制数据:
- 设置超时时间为0
- 函数返回后,判断是否超时:
如果超时,从partial中取数,
如果未超时,从rbuf中取数。