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

client rednet.receieve() gets seemingly random message

Started by GrumpyCrouton, 17 August 2017 - 12:04 AM
GrumpyCrouton #1
Posted 17 August 2017 - 02:04 AM
Hi all, I recently had a question here http://www.computercraft.info/forums2/index.php?/topic/28877-computercraft-simple-program-not-working-correctly/page__p__268746__hl__grumpycrouton__fromsearch__1
to which I got some help solving an issue I was having.

With all of the new things I learned from that post, I decided to rewrite my code.

Along with this rewrite, came some new issues that I'm not sure how to handle.

Here is my new code:

Server:



print("Starting server")
sleep(2) --# Give the other computers time to turn on.
rednet.open("left")

local clients = {rednet.lookup("lightControl")}
local sides = {"left", "top", "right", "bottom", "back"}

print("Checking clients")
if next(clients) == nil then
    error("No clients found!")
end

print("Starting loop")

while true do
        if rs.getInput("back") then
            local client = clients[math.random(#clients)]
            local side = sides[math.random(#sides)]
            rednet.broadcast("Off")
            print("All lights toggled off.")
            rednet.send(client, side)
            print(client.." "..side.." light enabled > play")
            sleep(10)
        else
            for i=1,#clients do
                rednet.broadcast("Off")
                print("All lights toggled off.")
                for s=1,#sides do
                    print(clients[i].." "..sides[s].." tripped > strobe")
                    rednet.send(clients[i], sides[s])
                    sleep(.5)
                    rednet.send(clients[i], "Off")
                end
            end
        end
        os.pullEvent("redstone")
end

Client:



rednet.open("front")
rednet.host("lightControl", os.getComputerLabel())

local sides = {"left", "top", "right", "bottom", "back"}

while true do
    print("Waiting for input...")
    local id, message = rednet.receive()
    message = tostring(message)
    print("Message recieved: "..message)
    
    if message == "Off" then
        print("Light toggled off")
        for s=1,#sides do
            rs.setOutput(sides[s], false)
        end
    else
        print(message.."light toggled on")
        rs.setOutput(message, true)
    end
end

I feel much better about this code, however I am having a pretty strange issue.

When I start the clients, I get a message "Waiting for input…" as expected - and then I start the server.

When I start the server, the client gets an error, but the server keeps going, doing it's thing.

On the client I get this error:

"client:19: Invalid side."

I get this error because for some reason the server sends a message that is like "table: ########" (where the number signs are random numbers/letters) like the following screenshots:

http://prntscr.com/g9fguz

http://prntscr.com/g9fgww

http://prntscr.com/g9fgyj

I'm not really sure why this is happening, but I would love any advice anyone can give me
KingofGamesYami #2
Posted 17 August 2017 - 02:38 AM
Are you sure no other computers are broadcasting in the area? This would be a major issue, especially if you were to try using this on a server. I would recommend checking for invalid sides (non-strings or strings that aren't within the table returned by rs.getSides()).
GrumpyCrouton #3
Posted 17 August 2017 - 02:41 AM
Are you sure no other computers are broadcasting in the area? This would be a major issue, especially if you were to try using this on a server. I would recommend checking for invalid sides (non-strings or strings that aren't within the table returned by rs.getSides()).

There are 2 clients and 1 server. They are the only computers near the area, and they are connected via wired modems.
Dog #4
Posted 17 August 2017 - 03:55 AM
The table you're receiving is probably related to rednet.host. That is probably also triggering your invalid side error. You could make better use of rednet.host/protocols by changing your rednet.receive command to this:

local id, message = rednet.receive("lightControl") --# only receive messages with the protocol "lightControl"

Then alter your rednet.send/broadcast commands like so…

rednet.send(client, data, "lightControl") --# send using the "lightControl" protocol
rednet.broadcast("Off", "lightControl") --# broadcast using the "lightControl" protocol

This should eliminate the table you are receiving and block out any other unwanted network noise due to protocol handling.
GrumpyCrouton #5
Posted 17 August 2017 - 04:48 AM
The table you're receiving is probably related to rednet.host. That is probably also triggering your invalid side error. You could make better use of rednet.host/protocols by changing your rednet.receive command to this:

local id, message = rednet.receive("lightControl") --# only receive messages with the protocol "lightControl"

Then alter your rednet.send/broadcast commands like so…

rednet.send(client, data, "lightControl") --# send using the "lightControl" protocol
rednet.broadcast("Off", "lightControl") --# broadcast using the "lightControl" protocol

This should eliminate the table you are receiving and block out any other unwanted network noise due to protocol handling.

I've done that, and now my clients will not recieve anything sent by rednet.send, but it is recieving things from rednet.broadcast

here is my code:

server


print("Starting server")
sleep(2) --# Give the other computers time to turn on.
rednet.open("left")

local rednetWord = "lightControl"

local clients = {rednet.lookup(rednetWord)}
local sides = {"left", "top", "right", "bottom", "back"}

print("Checking clients")
if next(clients) == nil then
	error("No clients found!")
end

print("Starting loop")

while true do
		if rs.getInput("back") then
		
			local client = clients[math.random(#clients)]
			local side = sides[math.random(#sides)]
			
			rednet.broadcast("Off", rednetWord)
			print("All lights toggled off.")
			rednet.send(client, side, rednetWord)
			sleep(5)
			rednet.send(client, "Off", rednetWord)
			print(client.." "..side.." light triggered > play")
			
		else
			for i=1,#clients do
				rednet.broadcast("Off", rednetWord)
				print("All lights toggled off.")
				for s=1,#sides do
					print(clients[i].." "..sides[s].." triggered > strobe")
					rednet.send(clients[i], sides[s], rednetWord)
					sleep(1)
					rednet.send(clients[i], "Off", rednetWord)
				end
			end
		end
		os.pullEvent("redstone")
end

Client



rednet.open("front")
rednet.host("lightControl", os.getComputerLabel())

local sides = {"left", "top", "right", "bottom", "back"}

print("Waiting for input...")

while true do

	local id, message = rednet.receive("lightControl")
	print("Message recieved: "..message)
	
	if message == "Off" then
		print("All light toggled off")
		for s=1,#sides do
			rs.setOutput(sides[s], false)
			sleep(.3)
		end
	else
		rs.setOutput(message, true)
	end
	
end

EDIT–
I'm thinking maybe they lost their labels for some reason checking that now
EDIT2–
No go :/ I am completely clueless to why this isn't receiving
Edited on 17 August 2017 - 02:54 AM
Dog #6
Posted 17 August 2017 - 05:24 AM
If your computers didn't have labels, you'd get a hosting error from rednet when two of them in range tried to host the same protocol with the same identifier (in this case the identifier would be nil if the computers didn't have labels).

I made two changes - one fixed the problem, the other is just a good idea…

Change 1: Eliminate the sleep(.3) statement in the client - that's why you're losing messages.

Change 2: On the server, move the rednet.broadcast statement and "All lights toggled off" print statement out of the 'for i = 1, #clients' loop, as they only need to be done once (not once per loop).
Edited on 17 August 2017 - 03:26 AM