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

rednet protocol issue

Started by Kouksi44, 13 August 2014 - 05:34 PM
Kouksi44 #1
Posted 13 August 2014 - 07:34 PM
Hey,

I am currently writing an API to send files over rednet.

In my API I am offering the sender the possibility to give the file an "alias". This alias will be the name of the file on the receiver computer.

I wanted to send this alias by using it as the protocol name of the message.

Now I have to get this protocol at the receivers computer to get the name of the file and thats the point where my program crashes.

Here´s the code of the API :


function sendFile(path,alias,receiverID)

openSide()
if fs.exists(path)	  
  then
   local g=fs.open(path,"r")
   local file=g.readAll()
  else print("error:invalid path")
end
if alias==""	  
  then
   local filealias=fs.getName(path)
	else filealias=alias
end

rednet.send(receiverID , file , filealias)
end

function receiveFile(path,timeout)
openSide()
senderID,message,protocol=rednet.receive(timeout)
  local l=fs.open(path..protocol,"w")
  l.write(message)
end

In line 49 my program crashes saying: attempt to concatenate string and nil;

Obviously the main problem is this part :

senderID,message,protocol=rednet.receive(timeout)

Here I try to get the protocol of the message, but somehow this doesn´t work :/

Any ideas how to fix this ?

Thank you in advance,

Kouksi44
Bomb Bloke #2
Posted 13 August 2014 - 08:07 PM
Consider what happens when the timeout is reached, or any rednet message arrives without a specified protocol. Try checking to see whether a valid protocol was received:

local function receiveFile(path,timeout)
	openSide()
	local senderID,message,protocol = rednet.receive(timeout)
	
	if protocol then
		local l = fs.open(path..protocol,"w")
		l.write(message)
		l.close()
	end
end

You may consider making further checks to see if the message came from a valid source and specified a valid file name.
Kouksi44 #3
Posted 13 August 2014 - 08:44 PM
Thank you for your answer !

But my problem at the moment is, that it seems like no protocol is delivered with the message.
I tried printig the protocol to the screen but all I get is blank :/

What you told is correct and I will implement your suggestions but I don´t see how your solution solves my main problem !

So I think I am doing something wrong trying to get the protocol used by the message ?!
Kouksi44 #4
Posted 13 August 2014 - 08:50 PM
Nevermind.

I came to a solution on my own :)/>

I think it´s pretty useless to set the file name by sender.
So the file name is now set by the receiver when he calls the receiveFile() function .

Anyway thank you for your help :)/>
Bomb Bloke #5
Posted 14 August 2014 - 04:19 AM
For what it's worth, I believe you were retrieving the protocol correctly. I suspect the issue was in how you were sending it.
Dragon53535 #6
Posted 14 August 2014 - 06:04 AM
I think that rednet.send() protocol is actually supposed to be in square brackets such as ["myprotocol"] looking at the wiki page for rednet.send it does show that Wiki link.

I tested for myself, and it doesn't work. the brackets are there just for show it seems on the wiki page.

Okay, testing again i was able to get the protocol if i used rednet.receive(100) Testing with a slightly modified version of your code to see what the problem is. Now the only problem that i'm seeing could happen is if you DON'T send a protocol, in which case you could check for if the protocol == nil and then you shouldn't be getting an error to combine a string and nil.


Upon completely recreating your code AND TESTING IT, i can say that there is no error in the code you have posted on the top. I used filenet.receiveFile("apis/",100) and filenet.sendFile("test","senior",1) (test being the file that sent the file :P/>) and upon doing so i found my little testing program nestled inside my apis folder as senior.

Which means that you the USER used your own program incorrectly.

Also side note on my heavily edited post. Are you using CC 1.6?
Edited on 14 August 2014 - 04:47 AM
natedogith1 #7
Posted 14 August 2014 - 06:20 AM
'if alias=="" then' probably should have been 'if alias and alias=="" then', since you'd have a nil protocol if the alias wasn't passed in. Also, instead of 'path..protocol' you should use 'fs.combine(path,protocol)' it's what it's there for, and it cleans up the path, making it easy for you to check if the file location is in a folder higher than it's supposed to be.
Bomb Bloke #8
Posted 14 August 2014 - 06:51 AM
I think that rednet.send() protocol is actually supposed to be in square brackets such as ["myprotocol"] looking at the wiki page for rednet.send it does show that Wiki link.

I tested for myself, and it doesn't work. the brackets are there just for show it seems on the wiki page.

Square brackets basically mean "this bit's optional". They're a fairly long-standing documentation convention.

'if alias=="" then' probably should have been 'if alias and alias=="" then', since you'd have a nil protocol if the alias wasn't passed in.

'if alias == "" or not alias then', maybe.
Edited on 14 August 2014 - 04:53 AM
Dragon53535 #9
Posted 14 August 2014 - 07:00 AM
I think that rednet.send() protocol is actually supposed to be in square brackets such as ["myprotocol"] looking at the wiki page for rednet.send it does show that Wiki link.

I tested for myself, and it doesn't work. the brackets are there just for show it seems on the wiki page.

Square brackets basically mean "this bit's optional". They're a fairly long-standing documentation convention.

Okay well that's a bit of information i didn't know lol, anyways the point of the post still stands, his program had nothing that would stop it's working condition and cause it to error and mess up. The only problem i can see for him to get to the stage he got to was that he either did not specify the path correctly, or did not send over the alias. By creating a copy of the code onto two separate computers in a testing world i was able to send the files across fully intact.
Bomb Bloke #10
Posted 14 August 2014 - 07:17 AM
Yeah, my point was that you'll likely see the brackets elsewhere (eg when looking at the documentation for the command line tools of your real computer's OS), so if they do turn up, it's generally safe to assume they mean the same thing.

Best I can make out, nate spotted the issue correctly - when sending, if you don't specify an alias at all then filealias remains nil and the receiver will error out as a result.

Edit:

Actually, reading the sending function properly, I can't see how it'd work at all - variable localisation is up the creek. Both filealias and file will likely be nil when it comes time to send (definitely, in the case of file).

What the heck, here's a re-write:

local function sendFile(path,alias,receiverID)
	openSide()

	if not fs.exists(path) then
		print("error:invalid path")
		return
	end

	local g = fs.open(path,"r")
	rednet.send(receiverID , g.readAll() , (alias == "" or not alias) and fs.getName(path) or alias)
	g.close()
end

local function receiveFile(path,timeout)
	openSide()
	senderID,message,protocol=rednet.receive(timeout)
	
	if protocol then
		local l = fs.open(fs.combine(path,protocol),"w")
		l.write(message)
		l.close()
	else print("error:no valid response") end
end
Edited on 14 August 2014 - 05:34 AM
Dragon53535 #11
Posted 14 August 2014 - 05:38 PM
Yeah, my point was that you'll likely see the brackets elsewhere (eg when looking at the documentation for the command line tools of your real computer's OS), so if they do turn up, it's generally safe to assume they mean the same thing.

Best I can make out, nate spotted the issue correctly - when sending, if you don't specify an alias at all then filealias remains nil and the receiver will error out as a result.

Edit:

Actually, reading the sending function properly, I can't see how it'd work at all - variable localisation is up the creek. Both filealias and file will likely be nil when it comes time to send (definitely, in the case of file).

Meh, i just got his code off pastebin and recreated it to actually work i guess.
Kouksi44 #12
Posted 15 August 2014 - 12:47 AM
Hm , I see that the mistake was Made on my side :/ anyways i have rewritten my code a bit and now it functions properly for me.
In the end I just put away the alias option in the send function and put it in the receive function .