[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Can there be a better way of doing non-blocking data reads with LuaSocket?
- From: "Sam Roberts" <vieuxtech@...>
- Date: Sun, 9 Nov 2008 22:24:54 -0800
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)
end
local size = assert(tonumber(prefix or 4096))
local data, emsg, partial = client:receive(size)
if not data and partial ~= "" then
return partial
else
return data, emsg
end
end