2011-07-20 38 views
0

我有一个使用NSE(nmap脚本引擎)递归地发送命令并通过套接字连接接收数据的Lua脚本。它似乎通常工作,直到它得到一个大的字符串回来,然后它往往截断收到的数据。在发送下一个命令时,在之后的数据截断(应该在前一个命令中接收到)通过(最终跟随正确的数据)。下面简化了示例输出。注意“data38”被截断,并继续在命令的下一个实例:Lua套接字接收字符串大小

"send command1" 
"recieved data =" 
data1 
data2 
data3 
.... 
.... 
.... 
data37 
da 
**returning** 
"send command2" 
"received data =" 
ta38 (should be from command1) 
data39 (should be from command1) 
etc etc etc 

示例代码如下:

local function blah(id) 

local response 
local data 
local commmand 

command = "dir..id" 

socket:send(command) 
response,data = socket:receive() 

print(data) 

--do recursion her depending on data results. 

print "**returning**" 
return 

action = function(host,port) 
    socket = nmap.new_socket() 
    socket:connect(host,port) 
    socket:set_timeout(15000) 
    test = blah(id) 
return test 

这个问题似乎是套接字只能接收一定数量的字节,然后返回。 Socket是一个全局变量,因为我不想为每个“blah”实例打开一个新的套接字。有没有什么办法可以让套接字等待接收所有的数据(直到字符串为空例如终止),然后打印数据?

更新 我一直在尝试不同的方法来传递一个大小参数来接收方法,如说: http://w3.impa.br/~diego/software/luasocket/tcp.html 然而,这些似乎都没有任何效果如。

response,data = socket:receive(65536) 
response,data = socket:receive('a*') 

回答

1

传递字符串或二进制数据时通过网络是先通过字段的大小我一直使用的溶液。然后你可以运行接收,直到它匹配已知的长度。这意味着服务器将是这样的:

command,err_msg=socket:receive() 
-- build response 
socket:send(string.len(response)) 
-- Note, you should also check for incomplete sends and 
-- run this in a loop until all data has been sent 
socket:send(response) 

而且客户端将如下所示:

socket:send(command) 
resp_len,err_msg = socket:receive() 
response="" 
repeat 
    resp_cur,err_msg = socket:receive(resp_len - string.len(response)) 
    if resp_cur then 
    response = response .. resp_cur 
    end 
until !resp_cur or string.len(response) >= resp_len end 
-- handle any errors from an incomplete receive here 
+0

每次调用函数时我都不知道数据的大小,数据大小可能会有所不同。我试过socket:receive('a *'),它从套接字读取,直到连接关闭。但结果是一样的。 – greatodensraven

+0

这就是为什么我建议你*先发送尺寸*。 – BMitch

+0

你的意思是类似于:response,data = socket:receive(65536)??我试图按照这些方式实现某些内容,但似乎仍然没有区别 – greatodensraven

0

我相信这是在luasocket库(由电晕SDK至少使用的版本)中的错误这会导致它通过TCP间歇地破坏大数据包。 Corona SDK开发人员已经证实了这一点。怀疑问题是luasocket库不能正确处理TCP重试请求。我试图通过将帧大小限制为小于标准网络(ipv4)MTU来规避错误,希望这可以避免数据包碎片并防止出现问题。我通过将分组数据自己制动成更小的帧,然后在另一端重新组装来实现这一点。对于IPV4的MTU通常是576字节,我试图用512来保证安全。

0

只是为了澄清,socket.receive的正确参数是'*a'而不是'a*' - 这可能是您没有从套接字接收所有数据的原因。