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

rednet:87: Expected number

Started by Feolthanos, 28 July 2017 - 01:36 PM
Feolthanos #1
Posted 28 July 2017 - 03:36 PM
Hi, I'm currently trying to make a little program that sends files from a PC to a server, so that you can access it everywhere and so you can send it to other PC's. But I can't seem to make it work, could someone please help me ?

Send script:

print("What file do you want to send ?")
input = read()
file = fs.open(input, "r")
rednet.open("left")
print("Connecting to the server...")
rednet.broadcast("connect")
event, id, msg = os.pullEvent("rednet_message")
if msg == "connected" then
print("Connected! sending file...")
while true do
  local line = file.readLine()
  rednet.broadcast(tonumber(line))
  if line == nil then break end
end
end
print("Connection refused")

Server script:

while true do
rednet.open("left")
event, id, msg = os.pullEvent("rednet_message")
if msg == "connect" then
  rednet.send("connected")
  print("A FTP user has connected")
  event, msg = os.pullEvent("rednet_message")
  file = fs.open(msg, "w")
  while true do
   event, msg = os.pullEvent("rednet_message")
   file.writeLine(line)
  end
  fs.close()
else
  rednet.send("Denied")
end
end
Edited on 28 July 2017 - 01:54 PM
The Crazy Phoenix #2
Posted 28 July 2017 - 03:39 PM
The server won't receive any messages because you haven't opened any modems.
Modems only need to be opened for receiving, you don't need to open them for sending.

tonumber("connect") is nil, that's the cause of the error. "connect" is not a valid string representation of a number
Edited on 28 July 2017 - 01:41 PM
Feolthanos #3
Posted 28 July 2017 - 03:45 PM
Thanks for your response, but even if I open a modem on the server and just use ("connect") instead of (tonumber("connect)) I still get the same error
Dog #4
Posted 28 July 2017 - 04:52 PM
rednet.send requires two parameters. The target and the message.

rednet.send(1, "connect") --# note that the target computer id is first, then the message is second

Also, your send script never closes the file it opens - this means the file will be inaccessible, after the program exits, until a reboot.

You might also want to move this line in your sender script

if line == nil then break end
one line up so you don't bother sending a nil message to the receiver, unless that's your intention.

On your server script you have…

event, message = os.pullEvent("rednet_message")
that should be…

event, id, message = os.pullEvent("rednet_message")
Edited on 28 July 2017 - 02:59 PM
Feolthanos #5
Posted 28 July 2017 - 05:11 PM
Thanks, I made the changes like you said, but the server still says: "rednet:87: Expected Number"
Dog #6
Posted 28 July 2017 - 05:17 PM
Then you most likely aren't passing a number for the client ID. Post your code as it is now so I can see what you're working with.
Feolthanos #7
Posted 28 July 2017 - 05:19 PM
If I use rednet.broadcast() instead of rednet.message() the system works kind of. It then sends the name of the file and the server creates the file, but the file content is not being transferred :l

Send script:

print("What file do you want to send ?")
input = read()
file = fs.open(input, "r")
rednet.open("left")
rednet.broadcast(input)
print("Connected! sending file...")
while true do
local line = file.readLine()
if line == null then break end
rednet.broadcast(line)
end

Server script:

while true do
rednet.open("left")
event, id, msg = os.pullEvent("rednet_message")
file = fs.open(msg, "w")
print("A user is sending a file named: "..msg)
while true do
  event, id, msg = os.pullEvent("rednet_message")
  file.writeLine(line)
end
print("File Received!")
fs.close()
end
Edited on 28 July 2017 - 03:19 PM
Dog #8
Posted 28 July 2017 - 05:25 PM
OK, a couple of things…

1. null is not a Lua keyword, the line in the sender code should use nil instead of null

if line == nil then break end

2. Your server script is writing line to the file, not msg which is what is being received. It should be…

file.writeLine(msg)
Feolthanos #9
Posted 28 July 2017 - 05:28 PM
After editing those 2 things, the file I want to send is still empty :l
Dog #10
Posted 28 July 2017 - 05:38 PM
Post your code.

Also, I just noticed that in your receiver code you're using fs.close instead of file.close - there is no fs.close, the close function is exposed when you open a file and is tied to your file handle, not fs.

EDIT:
OK, I just noticed that your receiver code will never exit the receive loop and thus never close the file. Here's how I would fix it:

In your sender code I would go ahead and allow the nil to be sent, then break that loop (so move 'if line == nil then break end' below 'rednet.broadcast(line)'). I realize this basically reverses what I recommended earlier - my apologies for the confusion.

In your receiver code I would look to see if msg is nil and break the loop when it is, like so…

event, id, msg = os.pullEvent("rednet_message")
if msg == nil then break end
file.writeLine(msg)
Edited on 28 July 2017 - 05:16 PM
Feolthanos #11
Posted 29 July 2017 - 11:26 AM
Here's the updated code:

Send script:

term.clear()
term.setCursorPos(1,1)
print("What file do you want to send ?")
input = read()
file = fs.open(input, "r")
rednet.open("left")
rednet.broadcast(input)
print("Connected! sending file...")
while true do
local line = file.readLine()
rednet.send(1,line)
sleep(0.1)
if line == nil then break end
print("sending "..line)
end

Server script:

term.clear()
term.setCursorPos(1,1)
print("FTP Server running:")
while true do
rednet.open("left")
event, id, msg = os.pullEvent("rednet_message")
file = fs.open(msg, "w")
event, id, msg = os.pullEvent("rednet_message")
if msg == nil then break end
file.writeLine(msg)
print("Received "..msg)
end
file.close()

I now get a server error: "FTPserver:10: attempt to index ? (a nil value)"
But it writes the 1st line of the file and closes it now.
Feolthanos #12
Posted 29 July 2017 - 11:33 AM
Nevermind, I fixed the problem and everything works now, I noticed that I put rednet.open(), and file = fs.open()in the loop. That's why it tried to open the file with the message name containing 1 line (So the PC was spammed with a file with the name of 1 line xDD)
Dog #13
Posted 29 July 2017 - 04:27 PM
Glad you got it working! If you have any other questions regarding this code, please post in this thread so anyone helping you has a history of what's already been done.
Feolthanos #14
Posted 31 July 2017 - 12:00 PM
Well, the file transfer works for now, but there's a little something that I want to solve. My user creation program saves all the files with a user number (user#01 etc.) but can I make it so that it keeps track of how many users it has created and automatically saves it with a higher value ID (user#002 etc.) ?
The Crazy Phoenix #15
Posted 31 July 2017 - 12:49 PM
Well, the file transfer works for now, but there's a little something that I want to solve. My user creation program saves all the files with a user number (user#01 etc.) but can I make it so that it keeps track of how many users it has created and automatically saves it with a higher value ID (user#002 etc.) ?

You could create a file that tracks the number, but that'd mean that the program breaks if you tamper with the save data.
Instead, try using fs.complete("user#", dir) and then using the length operator to count how many files start with "user#".
Then, to make sure, verify that the next index exists, and as long as it doesn't, keep incrementing.
In other words…


    local files = fs.complete("user#", dir)
    local index = #files + 1
    while (fs.exists("user#"..index)) do
        index = index + 1
    end
KingofGamesYami #16
Posted 31 July 2017 - 05:38 PM
If you put them all in a certain directory, you could just use

#fs.list( insert_dir_here )

to get the number of files. Add 1 to that and you've got the next user.