Lua套接字接收字符串大小

发布于 2024-11-25 03:07:40 字数 1260 浏览 1 评论 0原文

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

"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

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

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

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

I have a Lua script that recursively sends commands and receives data back over a socket connection, using NSE (nmap scripting engine). It seems to usually work, until it gets a large string back, then it tends to truncate the received data. On sending the next command, the data after the truncation, that should have been received in the previous command, comes through (followed eventually by the correct data). simplified sample output below. Note "data38" is truncated and continues in next instance of the command:

"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

sample code is as follows:

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

The problem seems to be that the socket can only receive a certain number of bytes, and then returns. Socket is a global variable, as I do not want to open a new socket for every instance of "blah". Is there any way I can make the socket wait to receive all the data (until the string is null terminated for example) and then print the data??

Update
I have been trying different approaches to pass a size parameter to the receive method, as stated in:
http://w3.impa.br/~diego/software/luasocket/tcp.html
However these seem to have no effect whatsoever eg.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

魂归处 2024-12-02 03:07:40

通过网络传递字符串或二进制数据时,我一直使用的解决方案是首先传递字段的大小。然后您可以运行接收,直到它与已知长度匹配。这意味着服务器将如下所示:

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

The solution I've always used when passing a string or binary data over the network is to first pass the size of the field. Then you can run the receive until it matches the known length. This means the server will look like:

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)

And the client would look like:

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
晒暮凉 2024-12-02 03:07:40

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

I believe there is a bug in the luasocket library (at least the version used by the Corona SDK) which causes it to intermittantly corrupt large packets over TCP. This has been confirmed by the Corona SDK developers. The issue is suspected to be that the luasocket library does not handle TCP Retry requests properly. I am attempting to circumvent the error by restricting my frame size to less than the standard network (ipv4) MTU, hopefully this will avoid packet fragmentation and prevent the problem arising. I am achieving this by braking up the packet data myself into smaller frames then reassembling at the other end. MTU for IPV4 is usually 576 bytes, im trying with 512 to be safe.

撩人痒 2024-12-02 03:07:40

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

Just to clarify, the correct parameter to socket.receive is '*a' not 'a*' - this may be why you are not receiving all the data from the socket.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文