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

Rednet Client/server Tutorial

Started by JGBrands, 26 October 2013 - 11:30 AM
JGBrands #1
Posted 26 October 2013 - 01:30 PM
Work In Progress

Greetings,

This is a tutorial to writing Client/Server applications using ComputerCraft. This could be considered an intermediate tutorial and deals with basic networking concepts used in real world software development. Due to the complexity of the subject (even though Rednet is extremely simplified compared to real world Sockets), this tutorial will be separated into different parts.

The following knowledge is assumed:
  • Good understanding of ComputerCraft.
  • You have sufficient knowledge in Lua, this is not a Lua tutorial.
If the above doesn't apply to you, the subject matter might be difficult to follow - especially the code.

Without further ado, let's jump right into it.

PART ONE: Understanding the Client/Server and Client Neutrality

In the first part of this tutorial, we will talk about why you would want to design a Client/Server application and what the benefits are. You'll be surprised to find out how much easier it is to write certain things and how much more robust your applications become.

The Client/Server model involves at least two programs, unsurprisingly called the client and the server. This model is most efficient for handing out data, authenticating and managing a fixed resource pool with many different peers. The server handles requests from one or more clients and then feeds back the information the client needs to operate. Some examples of Client/Server implementations include:
  • An authentication server that handles the logging in, registration and permissions of users (very useful)
  • A database that can be used by clients to have the same set of information to manipulate.
  • A control system for something that you do not want to have direct access, for example, a server that controls all the doors in your house.
The benefit to writing a server is that you don't have to reinvent the wheel every time you want to use the same functionality, it's like an API, but instead it is an application. For this tutorial we will be writing a simple system that controls doors. Part of this server will be some rudimentary authentication.

Challenges of writing a Client/Server system

The biggest challenge of writing these kind of applications is dealing with multiple clients at once. When multiple clients connect to your server, they will all be sending information to it, your server as a result has to send information back to these clients which they expect in a timely fashion. But what happens when a client is sending information while your server is already busy? In real world computer programming, the Operating System would simply put the packet in a queue until the server is ready to receive it, but ComputerCraft isn't that sophisticated.

Instead it would be easier to program a smaller application to run on a second server, you can call this the "command" server. The only job this server has is to wait for clients to send data to it, it'll put the data in a table and then feed it to the server when the server is ready for the next packet. However, this isn't needed usually as the amount of users accessing the Server at once is bound to be rather limited in ComputerCraft

Client Neutrality

The most important thing to realize is that your server, by default, does not know how many clients there are. If you create a new computer and install your client on it, your server still has to know how to deal with it. An important concept to understand is client neutrality. Client neutrality means that your server works in such a way that it doesn't care about what computer it is talking to or receiving orders from. All it needs is the ComputerID, which is sent by Rednet anyway.

Protocol

Just like in the real world, your server and client should be talking through means of a protocol. A protocol is a set of guidelines to which both the client and server communicate. Think of it as a language, just like English. When you send the sentence "hello" to me, I know you are greeting me. The same is true for a client/server protocol, if I send a message like "0" to the server, then the server would know I'm breaking the connection, for example.

If you're going to design a complex client and server program, then you will want to write a protocol first.


PART TWO: Writing A Simple Server

This is the simplest of servers, it simply waits for a packet from any user and then replies with the same packet. I will post the code first, and then explain it line by line.


rednet.open("back")
while true do
  id, msg = rednet.receive()
  rednet.send(id, msg)
  print("recv: '" .. msg .. "' from " .. id)
end

rednet.open("back")
Sets Rednet up for communication. Back refers to the position of your wireless modem. If you're not using a wireless modem then refer to the documentation of the peripheral you chose instead.

id, msg = rednet.receive()
This is is a breaking function (that means your code does not continue) that will wait for any packet to be sent to it. When the packet arrives, it'll put the ID (like an IP address) in the 'id' variable, and the packet data in the 'msg' variable.

Remember that I spoke of client neutrality? Your code should NOT rely on hard coded IDs, instead you should always reply to the same ID that you received the packet from (unless you have a very good reason not to, but even then you should think of a way to avoid using hard coded computer IDs).

rednet.send(id, msg)

This function will let you send a message from one computer to another, assuming it has opened itself for Rednet communication. The first parameter is the computer ID, the second parameter is the packet of data (a string).

You might think a string is a strange way of sending data over the network, but it's actually not that far off reality. Sockets send data in a stream of chars (an signed, one byte of data), but it usually is not human readable text (though it can be, in the case of the most simplified protocols!).

PART THREE: Writing a simple client

This one is as simple as the server.


rednet.open("back")
rednet.broadcast("hello")
-- Listening for life on mars
id,msg = rednet.receive()
print("recv: " .. id .. ": " .. msg)
-- ALIEN LIFE??
if msg == "hello" then
  rednet.send(id, "goodbye")
  id, msg = rednet.receive()
  print("recv: " .. id .. ": " .. msg)
end

Some new functions here, what do they do?

rednet.broadcast("hello")

Remember what I said about client neutrality? The reverse isn't exactly true for client to server communication. As there is usually only one server, you can actually get away with sending the packet to a specific computer ID. Still, you would not want to hard code this, rather as an argument to your client program, as an input prompt during runtime or even as a configuration option.

But, for the sake of this tutorial, we actually broadcast the hello packet. This sends the packet to all computers that have Rednet open for communication. Any server listening for this packet WILL receive it, and do something with it. In the case of our server, it just sends the same data right back at us.

The rest of the code should be familiar to your already.

PART THREE: Trying it out

Go ahead, start up your server and run your server application. If it went well, nothing should happen and your command prompt should be taken away. This is usually a good sign.

Now start up another computer and run the client we just wrote. You should see the following output.
recv: 0: hello
recv: 0: goodbye

You should be given back the command prompt, now go to your server. The terminal should have the following output
recv: 'hello' from 1
recv: 'goodbye' from 1

​Congratulations! You wrote your first Client-Server application, notice how the server still hasn't given back the command prompt to you? This is a good thing, the server is just sitting there, waiting for the next client to talk to. It's very lonely, so you might want to run your client a few more times.

Here's some exercises you should try:
  1. Copy your client to a floppy disk and put it on a different computer and run it, what do you notice?
  2. Copy your server to a different computer and run it, now run a client. What happens?
  3. What if you have multiple servers running at once?
  4. Modify your client and server, try establishing something of a protocol.
CONCLUSION

That's all for this chapter, in the next chapter we will write a very simple authentication server in preparation of our door controlling system. Stay tuned!
LDShadowLord #2
Posted 29 October 2013 - 12:49 PM
Excellent, though I wish you had chosen to use wired modems instead of wireless. Anyway, fantastic tutorial. Well written and clear. 9/10 Would Read Again :P/>