lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

LuaSocket doesn't have an obvious way to read whatever data is
available from a socket, if it isn't line delimited or of a known
size. I found a way, but it seems unnecessarily obscure.

For a project I'm working on, when a socket selects as receivable, I
want whatever data is available, and I push into another object. I
don't have any knowledge of how much might be there, and it's binary
data so using *l is out of the question.

Anyhow, I implemented the following, but I've some questions:

1 - is this a good way to do it? It seems to work, but also seems a hack.

2 - why is partial not nil if there is no partial data? It's always
"", even if emsg isn't "timeout".

3 - I'd like to replace the standard receive with mine, but every
client socket seems to get a different metatable. Can I get to the
table with LuaSocket's client TCP methods, and replace it's receive
with mine?

4 - any chance of making "*f" ("frame") a standard part of LuaSocket?

- data, emsg, partial = client:receive(pattern[, prefix])
- data, emsg, partial = client:receive("*f"[, size])

If pattern is not "*f", is identical to client:receive().

Otherwise, return as much data as is available, up to size bytes.  If size is
not specified, it defaults to 4096. This is useful for dealing with a TCP
stream without knowing the protocol. I.e., transparent proxying of TCP data as
it arrives.

This pattern requires setting client's timeout to 0, for non-blocking behaviour.
function receive(client, pattern, prefix)
  if pattern ~= "*f" then
    return client:receive(pattern, prefix)

  local size = assert(tonumber(prefix or 4096))
  local data, emsg, partial = client:receive(size)
  if  not data and partial ~= "" then
    return partial
    return data, emsg