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

Help with sending a table over rednet

Started by pofferman, 20 July 2015 - 07:09 PM
pofferman #1
Posted 20 July 2015 - 09:09 PM
Hey guys :)/>

So, i have a problem.

In my code i have a sender and a receiver.The sender will send a table, that contains 2 variables - Command and Message.

And the receiver will then print the msg (Unserialized) and then it will perform the command - txt.command().


My problem is, that the receiver will fail at running the code (Because the command is a string).

So does anyone have a solution to fix my program? like making the txt.command unstringed somehow?

So this is the receiver:


rednet.open("right")
function sayHi()
print("HI")
end

local sID, dst, msg = rednet.receive()
local txt = textutils.unserialize(msg)

print(msg)
print("------------------")
txt.command()

And this is the sender:


rednet.open("right")
local txt = textutils.serialize({command = "sayHi", message = "10 + 10 = 20"})
rednet.send(1, txt)

Thanks for your patience :)/>
wieselkatze #2
Posted 20 July 2015 - 09:31 PM
Depending on which version of computercraft you're using, you can actually send the table without serializing/unserializing it.
This way you could put the function in the table itself - if that's what you want. The codes would then look like this:

Sender:

rednet.open( "right" )
rednet.send( 1, { command = function() print( "HI" ) end; message = "10 + 10 = 20" } )

Receiver:

local sID, msg, dst = rednet.receive()

print( "------------------" )
msg.command()

Note that you can't print the serialized table anymore as it isn't able to output the stored function.

See 6 posts below

The other way would be to store your function ( it actually is on the receiving computer ) in a table and give it a name.
The receiving end would the look like the following, whereas the sender would stay the same.


local yourFunctions = {
	sayHi = function()
		print( "HI" )
	end;
}

local sID, msg, dst = rednet.receive()

print( "------------------" )
yourFunctions[ msg.command ]()

This way it would look up the name given in msg.command in your 'yourFunctions' table and run it. It wouldn't be crash proof as it is though, as you could call nil if you send a command name that is not declared.

#Edit:
Fixed the order of variables used with rednet.receive()
Edited on 21 July 2015 - 03:06 PM
pofferman #3
Posted 20 July 2015 - 10:30 PM
Hey, thanks for the quick reply.

But neither of your fixes worked.

For the first method you mentioned, the error msg says (at the receiver):
Attempt to call nil (at the last line)
Which means that the method, of sending a function inside a rednet msg doesnt work (Or we both missed something).

And for the second method, the error msg was (at the receiver):
Attempt to call nil (at the last line)

I found a typo where i replaced msg and dst at the receive command.
from this
local sID, dst, msg= rednet.receive()
to this
local sID, msg, dst = rednet.receive()

But it didnt work either when i fixed that.
So idk if i did anything wrong.
HPWebcamAble #4
Posted 21 July 2015 - 01:46 AM
If possible, you'd want to use the second method. Sending functions isn't necessarily bad, but if you can avoid it then do so.


wieselkatze accidentally switched the message and distance from rednet.receive, but it looks like you caught it.

But to clarify, this is correct:

local senderID, message, distance = rednet.receive()
Note that distance will be the protocol in CC 1.6+, but that shouldn't matter here.


Just to make sure I understand, this is what your code for the second method looks like?
Sending Computer

rednet.open("side")
rednet.send( receivingID , "funcName" )

Receiving Computer

rednet.open("side")

local senderID, msg, distanceOrProtocol = rednet.receive()

print( "Running func "..msg ) --# Might want to do this as a test

local funcs = {
  sayHi = function()
    print("hi")
  end
}

funcs[ msg ]()

You could also check that 'msg' is in the 'func' table before trying to call it:

if type( funcs[ msg ] ) == "function" then
  funcs[msg]()
else
  print("nope")
end
pofferman #5
Posted 21 July 2015 - 01:03 PM
Thanks dude :)/>

I didnt realize that you could do that :)/>

I got it to work by putting all my functions inside a table (At the receiver), and then send (from sender) a table that contains 2 strings - A message & A command.

Thanks dude :)/>
wieselkatze #6
Posted 21 July 2015 - 04:10 PM
Well, I haven't switched anything - just copied his code. I didn't check if the variables used by rednet.receive() were in the right order - that most probably was the problem then.
I personally don't use rednet anyway; I designed my own protocol that works better for me, hence why i didn't notice the mistake :P/>
pofferman #7
Posted 21 July 2015 - 04:21 PM
[deleted]
Edited on 21 July 2015 - 02:22 PM
MKlegoman357 #8
Posted 21 July 2015 - 04:22 PM
This way you could put the function in the table itself - if that's what you want.

If possible, you'd want to use the second method. Sending functions isn't necessarily bad, but if you can avoid it then do so.

It's not possible to send functions using rednet. Those just get converted to nils after sending.
wieselkatze #9
Posted 21 July 2015 - 05:05 PM
It's not possible to send functions using rednet. Those just get converted to nils after sending.

Wow, incredible I missed that - thanks!
jerimo #10
Posted 21 July 2015 - 05:16 PM
Couldn't you string dumo the function and string load in the other side though?

Edit: no idea what happened from here on out, sorry bout that
Edited on 21 July 2015 - 03:18 PM
MKlegoman357 #11
Posted 21 July 2015 - 05:53 PM
Couldn't you string dumo the function and string load in the other side though?

So anyone could string.dump() a virus to your computer? Sure! Also, you won't be able to save upvalues and bytecode might get corrupted after sending.
HPWebcamAble #12
Posted 21 July 2015 - 08:26 PM
If possible, you'd want to use the second method. Sending functions isn't necessarily bad, but if you can avoid it then do so.

It's not possible to send functions using rednet. Those just get converted to nils after sending.

I just kind of assumed it was possible if you did it in a table.

Good to know!
jerimo #13
Posted 21 July 2015 - 10:57 PM
Couldn't you string dumo the function and string load in the other side though?

So anyone could string.dump() a virus to your computer? Sure! Also, you won't be able to save upvalues and bytecode might get corrupted after sending.
True, but was wondering for curiosity more than security