{"id":901,"date":"2017-12-09T13:00:12","date_gmt":"2017-12-09T13:00:12","guid":{"rendered":"http:\/\/chewett.co.uk\/blog\/?p=901"},"modified":"2020-09-26T22:06:15","modified_gmt":"2020-09-26T21:06:15","slug":"raspberry-pi-cluster-node-03-basic-node-communication-two-nodes","status":"publish","type":"post","link":"https:\/\/chewett.co.uk\/blog\/901\/raspberry-pi-cluster-node-03-basic-node-communication-two-nodes\/","title":{"rendered":"Raspberry Pi Cluster Node \u2013 03 Basic node communication between two nodes"},"content":{"rendered":"\n<p>This post builds on the <a href=\"\/blog\/881\/raspberry-pi-cluster-node-02-packaging-common-functionality\/\">second step to create a Raspberry Pi Cluster Node<\/a> 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.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Designing the client-master Raspberry Pi Nodes<\/h2>\n\n\n\n<p>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.<\/p>\n\n\n\n<p>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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating the client code to talk to the cluster master<\/h2>\n\n\n\n<p>To use sockets to talk to the master we are going to need to import the socket module as below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import socket<\/pre>\n\n\n\n<p>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.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nserver_address = ('localhost', 31415)\nsock.connect(server_address)<\/pre><\/pre>\n\n\n\n<p>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 <code>localhost<\/code>&nbsp;as the address to point to my machine as I am running the scripts on the same machine for now.<\/p>\n\n\n\n<p>Once the&nbsp;<code>connect<\/code>method has been called there is a socket connection between the two scripts. We can use this to send and receive any kind of data.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">client_number = random.randint(1, 100000)\nsock.send(\"Hello World, I am client {num}\".format(num=client_number))<\/pre><\/pre>\n\n\n\n<p>I create random integer variable that will identify the client using the <code>random<\/code> module. Once this is done I send a &#8220;Hello World&#8221; message to the master using the <code>send<\/code> method of the newly created socket.<\/p>\n\n\n\n<p>To finish off the slave code I have a while True loop to keep sending data every 5 seconds.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">while True:\n    time.sleep(5)\n    sock.send(\"I am still alive, client: {num}\".format(num=client_number))<\/pre><\/pre>\n\n\n\n<p>Now I have some code that will send a &#8220;Hello World&#8221; message to the master. While this is a simple message and has little practical use it will be expanded on in future posts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating the master code to listen to clients<\/h2>\n\n\n\n<p>To create the master I again need to create a socket but instead of connecting to a specific address I use the <code>bind<\/code>&nbsp;method. This creates a socket on the local machine so that others can connect to it. The <code>bind<\/code> 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&nbsp;variable to show the other formats of using <code>bind<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nsocket.bind(('', 31415))\nsocket.listen(1)<\/pre><\/pre>\n\n\n\n<p>By passing in an empty string to bind I make it bind to any address that machine has. This is useful if you dont&nbsp;know whether your application will use an IP address or machine name. The port used is completely arbitrary&nbsp;and should be something over 1024.<\/p>\n\n\n\n<p>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.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">(clientsocket, address) = socket.accept()\nlogger.info(\"Got client at {address}\".format(address=address))<\/pre><\/pre>\n\n\n\n<p>Now we called <code>accept<\/code> 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.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">data_len = 1\nwhile data_len &amp;gt; 0:\n    data = clientsocket.recv(512)\n    data_len = len(data)\n    if data_len &amp;gt; 0:\n        print data<\/pre><\/pre>\n\n\n\n<p>The final piece of code loops through receiving&nbsp;data and printing it out. It will stop once there has been no data received from the <code>recv<\/code>&nbsp;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.<\/p>\n\n\n\n<p>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&#8217;t useful to run programs on the Raspberry Pi cluster it creates the framework for distributed communication.<\/p>\n\n\n\n<p>The full code is\u00a0<a href=\"https:\/\/github.com\/chewett\/RaspberryPiCluster\/releases\/tag\/v3.0\">available on Github<\/a>, any comments or questions can be raised there as issues or posted below.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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.<\/p>\n","protected":false},"author":1,"featured_media":903,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[122],"tags":[39,184,37,101],"class_list":["post-901","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-raspberry-pi-cluster","tag-linux","tag-python","tag-raspberry-pi","tag-raspberry-pi-cluster"],"wppr_data":{"cwp_meta_box_check":"No"},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/12\/rpi_cluster_03_basic_communication.jpg?fit=800%2C800&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p2toWX-ex","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":658,"url":"https:\/\/chewett.co.uk\/blog\/658\/distributed-computing-raspberry-pi-cluster\/","url_meta":{"origin":901,"position":0},"title":"Distributed computing on the Raspberry Pi Cluster","author":"Chewett","date":"September 23, 2017","format":false,"excerpt":"This post describes the planned setup for distributed computing on the Raspberry Pi Cluster. A basic distributed system A very basic distributed system will have one Raspberry Pi asking as a master machine. This will coordinate work among all of the slaves. Eventually, we will move away from having a\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/09\/distributed_computing_design.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/09\/distributed_computing_design.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/09\/distributed_computing_design.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/09\/distributed_computing_design.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":1839,"url":"https:\/\/chewett.co.uk\/blog\/1839\/raspberry-pi-cluster-node-08-slave-helper-functions\/","url_meta":{"origin":901,"position":1},"title":"Raspberry Pi Cluster Node &#8211; 08 Slave Helper Functions","author":"Chewett","date":"December 19, 2018","format":false,"excerpt":"This post builds on\u00a0my previous posts in the Raspberry Pi Cluster series\u00a0by adding a number of slave helper functions.\u00a0 This update will begin the process of fully automating the slaves. Preparing the Slaves for Automation Before the slaves are ready to be fully automated there are a number of commands\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_08_slave_functions.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_08_slave_functions.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_08_slave_functions.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_08_slave_functions.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":738,"url":"https:\/\/chewett.co.uk\/blog\/738\/raspberry-pi-cluster-github-repository\/","url_meta":{"origin":901,"position":2},"title":"Raspberry Pi Cluster Github Repository","author":"Chewett","date":"October 14, 2017","format":false,"excerpt":"This post is a summary of the plan for the Raspberry Pi Cluster project. Progress so far So far I have been creating a variety of scripts to see what you I can easily do with the cluster project. At the moment these scripts are spread across the nodes and\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/10\/github_raspberry_pi_start.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/10\/github_raspberry_pi_start.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/10\/github_raspberry_pi_start.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/10\/github_raspberry_pi_start.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":367,"url":"https:\/\/chewett.co.uk\/blog\/367\/overview-raspberry-pi-cluster\/","url_meta":{"origin":901,"position":3},"title":"Overview of the Raspberry Pi Cluster","author":"Chewett","date":"June 17, 2017","format":"gallery","excerpt":"Now I have the power supply and built the stacking system\u00a0I can show off the clusters initial state. Every Raspberry Pi in\u00a0the cluster Here are the 7 initial Pi's that are to become part of the cluster. Each have been given a codename to designate\u00a0its position in the cluster.\u00a0The Raspberry\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/05\/cluster_uncovered.jpg?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/05\/cluster_uncovered.jpg?resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/05\/cluster_uncovered.jpg?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/05\/cluster_uncovered.jpg?resize=700%2C400 2x"},"classes":[]},{"id":1872,"url":"https:\/\/chewett.co.uk\/blog\/1872\/raspberry-pi-cluster-node-09-multi-slave-master\/","url_meta":{"origin":901,"position":4},"title":"Raspberry Pi Cluster Node \u2013 09 Multi Slave Master","author":"Chewett","date":"January 2, 2019","format":false,"excerpt":"This post builds on\u00a0my previous posts in the Raspberry Pi Cluster series\u00a0by changing the master so that it accepts multiple slaves connecting to it. Creating a thread to handle each client Typically to handle multiple operations occurring at once in a program, you will use additional threads or processes. These\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_09_multi_slave_master.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_09_multi_slave_master.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_09_multi_slave_master.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_09_multi_slave_master.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":1913,"url":"https:\/\/chewett.co.uk\/blog\/1913\/raspberry-pi-cluster-node-10-more-advanced-connection-handling\/","url_meta":{"origin":901,"position":5},"title":"Raspberry Pi Cluster Node \u2013 10 More Advanced Connection Handling","author":"Chewett","date":"January 16, 2019","format":false,"excerpt":"This post builds on\u00a0my previous posts in the Raspberry Pi Cluster series\u00a0by improving the connection code so it wont crash when the master or slave disconnects. Using Exceptions to handle socket issues The improvements to the cluster code are going to add an exception to the communication code. This will\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/01\/rpi_cluster_10_advanced_connection_handling.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/01\/rpi_cluster_10_advanced_connection_handling.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/01\/rpi_cluster_10_advanced_connection_handling.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/01\/rpi_cluster_10_advanced_connection_handling.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts\/901","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=901"}],"version-history":[{"count":4,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts\/901\/revisions"}],"predecessor-version":[{"id":2652,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts\/901\/revisions\/2652"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/media\/903"}],"wp:attachment":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=901"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=901"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=901"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}