This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Fauxm's profile picture

[SOLVED] Sending tables over rednet.

Started by Fauxm, 09 June 2012 - 06:47 PM
Fauxm #1
Posted 09 June 2012 - 08:47 PM
Hello, I need to send a table over rednet, the table is of two user-inputted numbers, but when I try to send it over rednet, I get the error

rednet:350: string expected
Now, I figured that I can't directly send tables over rednet, but is there any way to send a string containing these two numbers, then have the receiver read them as two separate numbers?
archit #2
Posted 09 June 2012 - 09:02 PM
Cant help with any errors without any code to see whats wrong :)/>/>

As for your question, yes you can easily send the info over as a string, as that's what rednet messages are comprised of.

Once you receive it on another you can parse what you need out of it, and recreate your table/tables.
Fauxm #3
Posted 09 June 2012 - 09:19 PM
Cant help with any errors without any code to see whats wrong :)/>/>

As for your question, yes you can easily send the info over as a string, as that's what rednet messages are comprised of.

Once you receive it on another you can parse what you need out of it, and recreate your table/tables.
Right, I figured I'd have to do that, I'm new to Lua, and coding in general, how would I go about doing that. Oh, and as for the source:
Essentially what I'm trying to do, is send some data, in the form of a message, and some "metadata", if you will. The data will be just a simple string/message, such as "Hello!", and the metadata will be who sent it, and who the final terminal is. Now, why I would need to send who sent it and who the final computer is, is because the data and metadata will be routed through other computers, which are set up to specifically be routers. The metadata won't actually be seen by the end user, but will tell the routers where to send the data to. In my planned network, There will be a larger network of routers, which route traffic to and from smaller networks, these router/network pairs I call "nodes". Example: Computer 1 is in node 1, it wants to send a message to computer 6, which is in node 2. Computer 1 types the message, and then is prompted by two questions, first: where is the final destination, which the user would type "6", and the next is "what is your router ID", to which the user would respond to whatever their node's router's computer ID would be. The "to" number and the current user's computer number (in this case, 1) are sent in the metadata, and will be interpreted by node 2's router, and computer number 6, which will read the "from" which contains the original sender ID, which in this case would be 1. I felt I needed to explain my goal before giving the source. Now, this is in no way complete, and I apologize for the sloppy code, but anyway:
Code for router:

rednet.open("top")
rednet.open("left")
currentVersion = "1.1.2"
function getVersion()
write("n")
write("Current version: "..currentVersion.."n")
write("n")
end
routeLoop = 5
function routeTraffic() --The function below is the core of the program.
write("Waiting for data...n")
senderId, data, distance = rednet.receive() --Receives data, the contents of the message.
write("Data received, waiting for metadata...n")
s, metadata, d = rednet.receive() --Receives metadata
write("Metadata received, routing...n")
metaNumbers = tonumber(metadata)
write(metaNumbers.."n")
sleep(1)
while routeLoop == 5 do
routeTraffic()
end
end
function gotoMenu() --Main menu of program.
write("Routing program.n")
write("Type 'version' to get current version, type 'route' to engage routing mode, and type 'exit' to exit the program.n")
write("n")
write("Note: routing mode is an infinate loop, and will continue to run until the program is terminatedn")
userMenuInput = nil
userMenuInput = io.read()
if userMenuInput == "version" then
getVersion()
gotoMenu()
end
if userMenuInput == "route" then
routeTraffic()
if userMenuInput == "exit" then
exit()
end
end
end
gotoMenu()
Code for message sender:
Note, line 14 is where I was trying to send a table, but I now realize that I'd have to send the metadata and have the routers read them.

rednet.open("top")
function sendMessage()
local fromID = os.computerID()
write("Type your message: n")
local data = io.read()
write("Type final terminal ID: ")
local toID = tonumber(io.read())
write("n")
write ("Type your router terminal ID: ")
local routerID = tonumber(io.read())
write("n")
rednet.send(routerID,data) --This sends the contents of the message, or "data".
sleep(1)
rednet.send(routerID,{ toID,fromID }) --This is the metadata of the message, it's information about the message itself, as in, where it's going, and who it's from. This information will not be read by the end user.
end
sendMessage()
Oh, and also, I'd just like to learn how to do this, not for someone else to rewrite my program. Other advice on how to not make it look bad, formatting and such is also helpful.
MysticT #4
Posted 09 June 2012 - 09:42 PM
You can use the serialize and unserialize functions of the textutils api. textutils.serialize converts any value you give to a string that represents that value, and textutils.unserialize gets that string and returns the values.
Example:
sender:

local t = {}
t[0] = 10
t[1] = read()
local msg = textutils.serialize(t)
rednet.open("top")
rednet.broadcast(msg)
receiver:

local id, msg = rednet.receive()
local t = textutils.unserialize(msg)
print(t[0])
print(t[1])

The only problem is that tables can't be serialized if they have references to itself, but someone wrote some serialization functions that can handle this, it's on the program library.
Fauxm #5
Posted 09 June 2012 - 10:12 PM
You can use the serialize and unserialize functions of the textutils api. textutils.serialize converts any value you give to a string that represents that value, and textutils.unserialize gets that string and returns the values.
Example:
sender:

local t = {}
t[0] = 10
t[1] = read()
local msg = textutils.serialize(t)
rednet.open("top")
rednet.broadcast(msg)
receiver:

local id, msg = rednet.receive()
local t = textutils.unserialize(msg)
print(t[0])
print(t[1])

The only problem is that tables can't be serialized if they have references to itself, but someone wrote some serialization functions that can handle this, it's on the program library.
Ah, yes, this works. Thanks!