2011-07-20 39 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*' - 這可能是您沒有從套接字接收所有數據的原因。