我有一个从Lua中的套接字读取的循环:
socket = nmap.new_socket()
socket:connect(host, port)
socket:set_timeout(15000)
socket:send(command)
repeat
response,data = socket:receive_buf("\n", true)
output = output..data
until data == nil
基本上,数据的最后一行不包含“\ n”字符,因此永远不会从套接字读取。但是这个循环只是挂起而永远不会完成。每当“\ n”分隔符无法识别时,我基本上都需要它返回。有谁知道这样做的方法?
干杯
更新 包含套接字代码
UPDATE2
好的我已经解决了使用“receive_bytes”方法等待“\ n”字符的初始问题。
新代码:
--socket set as above
repeat
data = nil
response,data = socket:receive_bytes(5000)
output = output..data
until data == nil
return output
这有效,我得到了大量完整的数据块。但我需要将缓冲区大小从5000字节减少,因为这在递归函数中使用,并且内存使用率可能会非常高。然而,我仍然遇到“直到”状态的问题,如果我将缓冲区大小减小到需要循环方法的大小,它只会在一次迭代后挂起。
UPDATE3 我使用string.match和receive_bytes解决了这个问题。我一次至少接收80个字节。然后string.match检查数据变量是否包含某种模式。如果是这样,它会退出。它不是最干净的解决方案,但它适用于我需要它做的事情。这是代码:
repeat
response,data = socket:receive_bytes(80)
output = output..data
until string.match(data, "pattern")
return output
答案 0 :(得分:1)
我认为在套接字中处理这种情况的唯一方法是设置超时。
以下链接有一些信息,但它在http套接字上:lua http socket timeout
还有这个(9.4 - 非抢先式多线程):http://www.lua.org/pil/9.4.html
关于Socket的一个很好的讨论可以在这个链接上找到:
http://nitoprograms.blogspot.com/2009/04/tcpip-net-sockets-faq.html
它是.NET,但概念很通用。
答案 1 :(得分:0)
请参阅更新3.因为数据的最后部分始终是相同的模式,所以我可以读取一个字节块,每次检查该块是否具有该模式。如果它具有模式,则意味着它是数据的结尾,附加到输出变量并退出。