Raspberry Pi Cluster Node – 03 Basic node communication between two nodes

This post builds on the second step to create a Raspberry Pi Cluster Node to create a hello world application across two different scripts. Here we will create a socket connection between the two and use it to send a message to the master.

Designing the client-master Raspberry Pi Nodes

To talk between the master and slave we are going to open a socket and send messages between them. For this first implementation, we are going to have a single node talking to the master.

The master will be designed to only listen to the first node that connects to it. This will not include code to handle nodes disconnecting prematurely but merely used to demonstrate how we can use sockets. Once we have a working setup we will work on improving the communication.

Creating the client code to talk to the cluster master

To use sockets to talk to the master we are going to need to import the socket module as below.

import socket

Now we have access to the socket library we can write some code to connect to another socket. First we create the socket in the slave and connect to the master socket.

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 31415)
sock.connect(server_address)

When we connect the socket address is given in a tuple. The first part of this is the address of the master and the second is the port number. I am using localhost as the address to point to my machine as I am running the scripts on the same machine for now.

Once the connectmethod has been called there is a socket connection between the two scripts. We can use this to send and receive any kind of data.

client_number = random.randint(1, 100000)
sock.send("Hello World, I am client {num}".format(num=client_number))

I create random integer variable that will identify the client using the random module. Once this is done I send a “Hello World” message to the master using the send method of the newly created socket.

To finish off the slave code I have a while True loop to keep sending data every 5 seconds.

while True:
    time.sleep(5)
    sock.send("I am still alive, client: {num}".format(num=client_number))

Now I have some code that will send a “Hello World” message to the master. While this is a simple message and has little practical use it will be expanded on in future posts.

Creating the master code to listen to clients

To create the master I again need to create a socket but instead of connecting to a specific address I use the bind method. This creates a socket on the local machine so that others can connect to it. The bind method uses a tuple again where the first argument is the hostname to bind to and the second is the port number. Here I have defined the tuple in place rather than using a separate variable to show the other formats of using bind.

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind(('', 31415))
socket.listen(1)

By passing in an empty string to bind I make it bind to any address that machine has. This is useful if you dont know whether your application will use an IP address or machine name. The port used is completely arbitrary and should be something over 1024.

The final line tells the socket to queue up a single connection in the buffer. Any more connections trying to join will be rejected. We only use one here since we will only be expecting a single connection.

(clientsocket, address) = socket.accept()
logger.info("Got client at {address}".format(address=address))

Now we called accept on the socket to accept a connection. This will wait for a connection to try and connect to the socket. Once it completes it will return the socket object and the address. We then log this so we know who has connected.

data_len = 1
while data_len > 0:
    data = clientsocket.recv(512)
    data_len = len(data)
    if data_len > 0:
        print data

The final piece of code loops through receiving data and printing it out. It will stop once there has been no data received from the recv call. This is a blocking call that only returns when data comes back. When it returns data with length 0 it means the connection has been closed.

Now I have created a client that will send hello world and a message every 5 seconds and the master which will print out these messages. While this application isn’t useful to run programs on the Raspberry Pi cluster it creates the framework for distributed communication.

The full code is available on Github, any comments or questions can be raised there as issues or posted below.

One Comment

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.