{"id":11331,"date":"2016-03-09T16:15:57","date_gmt":"2016-03-09T14:15:57","guid":{"rendered":"http:\/\/www.webcodegeeks.com\/?p=11331"},"modified":"2018-01-09T09:44:29","modified_gmt":"2018-01-09T07:44:29","slug":"python-network-programming-tutorial","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/","title":{"rendered":"Python Network Programming Tutorial"},"content":{"rendered":"<p>In this example we&#8217;ll talk about Network Programming with Python. By using Python 3.4 and its powerful <code>socket<\/code> module, at the end of this example we&#8217;ll have a messenger working.<\/p>\n<p>First of all, let&#8217;s make it very clear. Sockets are behind any kind of network communications done by your computer. We all know that, when you type a url in your browser, it&#8217;s connecting to a server somewhere in the world which receives a request, returns a response and then the connection is closed. All of this is made through sockets, always. It doesn&#8217;t matter if your are communicating through HTTP, UDP or whatever, there is a socket behind every one of those protocols.<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n[ulp id=&#8217;R7QVpFMZmjosABLC&#8217;]<br \/>\n&nbsp;<\/p>\n<p>Let&#8217;s have a quick overview of what a <em>socket<\/em> is: <em>A socket is one endpoint of a two-way communication link between two programs running on the network.<\/em><\/p>\n<p>Fancy, huh? Well, it&#8217;s not that hard. You can see sockets as an interface to communicate with another application, whether it is on the same computer or not. It&#8217;s just something that, given a connection, sends or receives some data through it. As the definition says, to send data through a socket, there must be another socket waiting for it at the other end of the line.<\/p>\n<p>Now, let&#8217;s differentiate two types of sockets here: <em>client sockets<\/em> and <em>server sockets<\/em>.<\/p>\n<ul>\n<li><strong>Client sockets<\/strong>: When you need to connect to a server and make an exchange, you open a client socket. Keep in mind that client sockets should live for only one exchange, and then be closed. If we could see how our browsers work (we actually can, but won&#8217;t), we&#8217;ll see that when we download a page, there is a socket being opened for every resource the page needs to be downloaded. No socket will be used to download two stylesheets, the browser will open a socket for each one of them.<\/li>\n<li><strong>Server sockets<\/strong>: In a server, to listen for connections from clients, we open a server socket and, instead of connecting to a host and port, we bind it to our host and some port in the machine. When a connection is received, <strong>it is not the server socket the one who receives the request and returns the response<\/strong>, the server socket only opens a client socket and connects it to the other end through a dynamically assigned port which will be recycled after the connection is closed.<\/li>\n<\/ul>\n<p>To see the basics of how to work with sockets, you can see this <a href=\"https:\/\/www.webcodegeeks.com\/python\/python-sockets-example\/\" title=\"Python Sockets Example\">example<\/a> and then come back to start working with our messenger application.<\/p>\n<h2>1. A P2P Messenger<\/h2>\n<h3>1.1. The Concept<\/h3>\n<p>An extremely simple messenger has two components, a sender and a receiver.<\/p>\n<p>The sender is the one responsible of sending messages. In most cases, it&#8217;s a component which, every time the user wants to send a message, opens a client socket, connects it to the recipient of the message, actually sends the message and then closes the socket.<\/p>\n<p>The receiver is the one responsible of receiving messages. It will be a component which binds a server socket to listen to connections and receive the data the client is sending.<\/p>\n<p>These two components should run on separated threads, as both will have to run inside a <code>while True<\/code>, for the receiver will have to accept connections as long as the user wants, and the sender will have to read user&#8217;s input as long as the application is running.<\/p>\n<h3>1.2. The Code<\/h3>\n<p>So, what will we use to make this work? Well, as I said before, I&#8217;ll use Python 3.4 and only two native modules: <code>socket<\/code> and <code>threading<\/code>. I&#8217;ll give an overview of the <code>threading<\/code> module, to make the example richer and simpler, but if you don&#8217;t know something already this <a href=\"https:\/\/www.webcodegeeks.com\/python\/python-threading-concurrency-example\/\" title=\"Python Threading \/ Concurrency Example\">example<\/a> would be a nice read for you.<\/p>\n<p>We will have two classes: <code>Receiver<\/code> and <code>Sender<\/code>. Both of them will extend <code>threading.Thread<\/code>.<\/p>\n<p>Let&#8217;s see the code of the <code>Receiver<\/code> first:<\/p>\n<p><span style=\"text-decoration: underline\"><em>messenger.py<\/em><\/span><\/p>\n<pre class=\"brush:python\">\r\n...\r\nclass Receiver(threading.Thread):\r\n\r\n    def __init__(self, my_host, my_port):\r\n        threading.Thread.__init__(self, name=\"messenger_receiver\")\r\n        self.host = my_host\r\n        self.port = my_port\r\n\r\n    def run(self):\r\n        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n        sock.bind((self.host, self.port))\r\n        sock.listen(10)\r\n        while True:\r\n            connection, client_address = sock.accept()\r\n            try:\r\n                full_message = \"\"\r\n                while True:\r\n                    data = connection.recv(16)\r\n                    full_message = full_message + data.decode(ENCODING)\r\n                    if not data:\r\n                        print(\"{}: {}\".format(client_address, full_message.strip()))\r\n                        break\r\n            finally:\r\n                connection.shutdown(2)\r\n                connection.close()\r\n...\r\n<\/pre>\n<p>As you can see, it&#8217;s a class that extends <code>threading.Thread<\/code> and defines two methods: <code>__init__<\/code> and <code>run<\/code>.<\/p>\n<p>The first one, <code>__init__<\/code>, is the method a class executes when instantiated. So, to instantiate this class we would run something like <code>Receiver(\"localhost\", 8881)<\/code>. This method will only receive the host and port, and assign them to properties of the class.<\/p>\n<p>The second method, <code>run<\/code>, is the one where the magic happens. It creates a server socket, bind it to the address provided on the initialization and define a maximum number of parallel connections of 10. Then, it enters a <code>while True<\/code> to accept connections as long as the thread is alive (we won&#8217;t worry about gracefully quitting the application). Every time this socket accepts a connection, the <code>accept<\/code> method will return a socket, which will be used to receive and send information, and the address of the client (see? The server socket only creates more sockets, it does not actually send or receive any data itself). Once we get this socket, which we called <code>connection<\/code>, we receive data until the connection is closed (the inner <code>while True<\/code>), and when the socket stops receiving data, we print the message we received. Of course, when the exchange is done, we close our end of the connection.<\/p>\n<p>Now, let&#8217;s have a look at the <code>Sender<\/code> class:<\/p>\n<p><span style=\"text-decoration: underline\"><em>messenger.py<\/em><\/span><\/p>\n<pre class=\"brush:python\">\r\n...\r\nclass Sender(threading.Thread):\r\n\r\n    def __init__(self, my_friends_host, my_friends_port):\r\n        threading.Thread.__init__(self, name=\"messenger_sender\")\r\n        self.host = my_friends_host\r\n        self.port = my_friends_port\r\n\r\n    def run(self):\r\n        while True:\r\n            message = input(\"\")\r\n            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n            s.connect((self.host, self.port))\r\n            s.sendall(message.encode(ENCODING))\r\n            s.shutdown(2)\r\n            s.close()\r\n...\r\n<\/pre>\n<p><code>Sender<\/code> is also a class that extends <code>threading.Thread<\/code>, and as such, also defines <code>__init__<\/code> and <code>run<\/code>.<\/p>\n<p>The <code>__init__<\/code> method has the same behaviour of Receiver&#8217;s, but the host and port are not the local ones to bind a server socket to, but the client&#8217;s one. We will connect to that endpoint.<\/p>\n<p>In the <code>run<\/code> method, we also have a <code>while True<\/code>, that receives an input from the user, opens a client socket and sends the message through it. Of course, after the exchange, we close the socket.<\/p>\n<p>Now, in a <code>main<\/code> method we will ask for the endpoints and start messaging:<\/p>\n<p><span style=\"text-decoration: underline\"><em>messenger.py<\/em><\/span><\/p>\n<pre class=\"brush:python\">\r\n...\r\ndef main():\r\n    my_host = input(\"which is my host? \")\r\n    my_port = int(input(\"which is my port? \"))\r\n    receiver = Receiver(my_host, my_port)\r\n    my_friends_host = input(\"what is your friend's host? \")\r\n    my_friends_port = int(input(\"what is your friend's port?\"))\r\n    sender = Sender(my_friends_host, my_friends_port)\r\n    treads = [receiver.start(), sender.start()]\r\n...\r\n<\/pre>\n<p>There we are requesting for the endpoint to bind the server to and the endpoint of the recipient of the message to connect to it. We instantiate both <code>Receiver<\/code> and <code>Sender<\/code> and start them. We store the threads in an array in case we want to do some stuff with them.<\/p>\n<p>There are a couple things to notice though. For example, we are not sending or receiving any response from the messages, the sender sends the message and closes the socket, does not expect anything back. Also, the receiver receives the message an closes the socket, if the client expects a response, it will wait forever (or for a really really long time). I don&#8217;t do it because it isn&#8217;t constructive to make the point, but we could use it to notify the sender that the message has arrived, and the user could see something like <em>&#8220;your message has arrived&#8221;<\/em>.<\/p>\n<p>Also, we are not closing the server socket, which in modern operating systems is not a problem, as the resources will be released as the main process stops, but we should write something to quit the application gracefully and close the socket correctly.<\/p>\n<p>So, this code, altogether, will look like this:<\/p>\n<p><span style=\"text-decoration: underline\"><em>messenger.py<\/em><\/span><\/p>\n<pre class=\"brush:python\">\r\nimport socket\r\nimport threading\r\n\r\nENCODING = 'utf-8'\r\n\r\n\r\nclass Receiver(threading.Thread):\r\n\r\n    def __init__(self, my_host, my_port):\r\n        threading.Thread.__init__(self, name=\"messenger_receiver\")\r\n        self.host = my_host\r\n        self.port = my_port\r\n\r\n    def listen(self):\r\n        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n        sock.bind((self.host, self.port))\r\n        sock.listen(10)\r\n        while True:\r\n            connection, client_address = sock.accept()\r\n            try:\r\n                full_message = \"\"\r\n                while True:\r\n                    data = connection.recv(16)\r\n                    full_message = full_message + data.decode(ENCODING)\r\n                    if not data:\r\n                        print(\"{}: {}\".format(client_address, full_message.strip()))\r\n                        break\r\n            finally:\r\n                connection.shutdown(2)\r\n                connection.close()\r\n\r\n    def run(self):\r\n        self.listen()\r\n\r\n\r\nclass Sender(threading.Thread):\r\n\r\n    def __init__(self, my_friends_host, my_friends_port):\r\n        threading.Thread.__init__(self, name=\"messenger_sender\")\r\n        self.host = my_friends_host\r\n        self.port = my_friends_port\r\n\r\n    def run(self):\r\n        while True:\r\n            message = input(\"\")\r\n            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n            s.connect((self.host, self.port))\r\n            s.sendall(message.encode(ENCODING))\r\n            s.shutdown(2)\r\n            s.close()\r\n\r\n\r\ndef main():\r\n    my_host = input(\"which is my host? \")\r\n    my_port = int(input(\"which is my port? \"))\r\n    receiver = Receiver(my_host, my_port)\r\n    my_friends_host = input(\"what is your friend's host? \")\r\n    my_friends_port = int(input(\"what is your friend's port?\"))\r\n    sender = Sender(my_friends_host, my_friends_port)\r\n    treads = [receiver.start(), sender.start()]\r\n\r\n\r\nif __name__ == '__main__':\r\n    main()\r\n<\/pre>\n<p>Now we execute it in two independent terminals (<code>$&gt; python3 messenger.py<\/code>), in one we will only fill the <em>&#8220;my host&#8221;<\/em> and <em>&#8220;my port&#8221;<\/em> prompts, as we want a server socket to be available before starting the first client. In the second one we fill everything, and then go back to the first and fill the client data. One console will look like this:<\/p>\n<pre class=\"brush:bash\">\r\nwhich is my host? localhost\r\nwhich is my port? 8881\r\nwhat is your friend's host? localhost\r\nwhat is your friend's port?8882\r\n\r\nhi!\r\n('127.0.0.1', 47893): hello! how are you?\r\nI'm fine! I love this messenger app. It's so simple. I LOVE it.\r\n('127.0.0.1', 47897): Yeah! It's awesome, and it's written in Python! I LOVE PYTHON!\r\n<\/pre>\n<p>And, the second one, will look like this:<\/p>\n<pre class=\"brush:bash\">\r\nwhich is my host? localhost\r\nwhich is my port? 8882\r\nwhat is your friend's host? localhost\r\nwhat is your friend's port?8881\r\n('127.0.0.1', 44624):\r\n('127.0.0.1', 44625): hi!\r\nhello! how are you?\r\n('127.0.0.1', 44627): I'm fine! I love this messenger app. It's so simple. I LOVE it.\r\nYeah! It's awesome, and it's written in Python! I LOVE PYTHON!\r\n<\/pre>\n<p>The messages containing an endpoint, are the ones received, and the other ones are sent messages. Now there is something really interesting. We are printing the client endpoint when we receive a message, notice anything weird? Yeah, the ports are never the same. Client sockets are bound to ports that the system provides dynamically and then recycled once the connection is closed (as we explained before). Another thing you might notice is the first empty message&#8230; I pressed enter accidentally on the first console, haha.<\/p>\n<p>This example was tested with localhost as I only have one computer connected to my network at home but, of course, if you have 2 machines connected to the same network, you can provide IPs instead of <em>&#8220;localhost&#8221;<\/em> and you&#8217;ll see the same results.<\/p>\n<p>Here it is. A very simple P2P (Peer to Peer) messenger. We now have a pretty good idea of how to handle sockets and send data through a network, this example should be useful for any kind of connection you need to make between applications, but to make it more useful, we&#8217;ll write something a lot more interesting now.<\/p>\n<h2>2. Something Bigger<\/h2>\n<h3>2.1. The Concept<\/h3>\n<p>We are going to make some modifications to this messenger to avoid using P2P, as it&#8217;s not a very popular protocol. Also, this modifications will allow us to write a chat room, instead of a conversation between two users.<\/p>\n<p>Our chat room application will consist actually of two applications: <em>a client<\/em> and <em>a server<\/em>.<\/p>\n<p>The server will receive connections from new users, save their information and receive messages to forward to all users present in the chat room. It will define a repository of users an a queue of messages. In one thread, we&#8217;ll have a server socket, and when a connection arrives, if it&#8217;s a connection request (some standard we&#8217;ll define, because we can) it will add a user to the repository, and if it&#8217;s a message it will parse and format the message and add it to the queue. On another thread, we&#8217;ll have a process that checks if the queue is not empty, and if it isn&#8217;t, it will pop a message out of it and send it to all the users (except the sender of course).<\/p>\n<p>The client will be pretty similar to our P2P messenger, but we need to add support for a user name and fix the messages that don&#8217;t apply to the problem now.<\/p>\n<h3>2.2. The Code<\/h3>\n<p>Let&#8217;s first have a look at the repositories in our messenger server:<\/p>\n<p><span style=\"text-decoration: underline\"><em>messenger\/server\/repository.py<\/em><\/span><\/p>\n<pre class=\"brush:python\">\r\nclass Queue:\r\n    def __init__(self):\r\n        self.queue = []\r\n\r\n    def add_message(self, sender, message):\r\n        self.queue.append({\"sender\": sender, \"message\": message})\r\n\r\n    def messages_waiting(self):\r\n        return len(self.queue) &gt; 0\r\n\r\n    def pop_message(self):\r\n        return self.queue.pop()\r\n\r\n\r\nclass Users:\r\n    def __init__(self):\r\n        self.users = []\r\n\r\n    def add_user(self, name, host, port):\r\n        self.users.append({\"name\": name, \"host\": host, \"port\": int(port)})\r\n\r\n    def all_users(self):\r\n        return self.users\r\n<\/pre>\n<p>As you can see, it is pretty simple. Both repositories are containers of an array, and just expose convenient methods to access the arrays within them. Now, let&#8217;s jump to the server.<\/p>\n<p>The server, as we said, has two components, <code>Receiver<\/code> and <code>Sender<\/code>, both of them extend <code>threading.Thread<\/code>.<\/p>\n<p>The <code>Receiver<\/code> is a thread that starts a server socket, receives messages and resolves them (decides whether it&#8217;s a new user or an actual message):<\/p>\n<p><span style=\"text-decoration: underline\"><em>messenger\/server\/messenger_server.py<\/em><\/span><\/p>\n<pre class=\"brush:python\">\r\n...\r\nclass Receiver(threading.Thread):\r\n    def __init__(self, my_host, my_port, queue, users):\r\n        threading.Thread.__init__(self, name=\"messenger_receiver\")\r\n        self.host = my_host\r\n        self.port = my_port\r\n        self.queue = queue\r\n        self.users = users\r\n\r\n    def resolve_message(self, message):\r\n        if \"connect_request\" in message:\r\n            print(\"connect request received\")\r\n            arr = message.split(\"|\")\r\n            if len(arr) == 4:\r\n                user_name = arr[1]\r\n                user_host = arr[2]\r\n                user_port = arr[3]\r\n                print(\"adding user: {}, {}, {}\".format(user_name, user_host, user_port))\r\n                self.users.add_user(user_name, user_host, user_port)\r\n            else:\r\n                print(\"invalid connect request...\")\r\n        elif \"from:\" in message:\r\n            print(\"received message... starting queueing process\")\r\n            arr = message.split(\"|\")\r\n            if len(arr) == 2:\r\n                sender_name = arr[0].replace(\"from:\", \"\")\r\n                print(\"adding message from {} to queue\".format(sender_name))\r\n                message_text = arr[1]\r\n                self.queue.add_message(sender_name, message_text)\r\n\r\n    def run(self):\r\n        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n        sock.bind((self.host, self.port))\r\n        sock.listen(10)\r\n        while True:\r\n            connection, client_address = sock.accept()\r\n            print(\"connection received from {}\".format(str(client_address)))\r\n            try:\r\n                full_message = \"\"\r\n                while True:\r\n                    data = connection.recv(16)\r\n                    full_message = full_message + data.decode(ENCODING)\r\n                    if not data:\r\n                        print(\"received message: [{}]\".format(full_message))\r\n                        self.resolve_message(full_message.strip())\r\n                        break\r\n            finally:\r\n                print(\"exchange finished. closing connection\")\r\n                connection.shutdown(2)\r\n                connection.close()\r\n...\r\n<\/pre>\n<p>Now, let&#8217;s talk in detail about what is going on here. As every class that extends <code>threading.Thread<\/code>, it defines <code>__init__<\/code> and <code>run<\/code>.<\/p>\n<p>On initialization this class will only receive an endpoint (host and port) to bind the server socket to and our queue and users repository.<\/p>\n<p>On the <code>run<\/code> method, it starts the server sockets and enters a <code>while True<\/code> where it will accept connections and receive messages. When a message arrives it throws them to another method called <code>resolve_message<\/code> that will decide whether it&#8217;s a new user or an actual message that it has to put in our queue to forward it to all connected users. The decision is pretty simple, we defined a standard where a new user should send a message containing &#8220;connect_request|-user_name-|-client_host-|-client_port-&#8220;, and a message should contain &#8220;from:-user_name-|-message_text-&#8220;. Every client that meets this standards will be able to use our chat room without any problem.<\/p>\n<p>Now, when do the messages actually get sent to other clients? Let&#8217;s see the <code>Sender<\/code> now:<\/p>\n<p><span style=\"text-decoration: underline\"><em>messenger\/server\/messenger_server.py<\/em><\/span><\/p>\n<pre class=\"brush:python\">\r\n...\r\nclass Sender(threading.Thread):\r\n\r\n    def __init__(self, queue, users):\r\n        threading.Thread.__init__(self, name=\"messenger_sender\")\r\n        self.queue = queue\r\n        self.users = users\r\n\r\n    def send(self, message, host, port):\r\n        print(\"sending message {} to {}\".format(message, str((host, port))))\r\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n        try:\r\n            s.connect((host, port))\r\n            s.sendall(message.encode(ENCODING))\r\n        finally:\r\n            print(\"message has been sent. closing connection\")\r\n            s.shutdown(2)\r\n            s.close()\r\n\r\n    def run(self):\r\n        while True:\r\n            if self.queue.messages_waiting():\r\n                print(\"there are messages on queue. popping one\")\r\n                message = self.queue.pop_message()\r\n                users = self.users.all_users()\r\n                for user in users:\r\n                    if user.get(\"name\") != message.get(\"sender\"):\r\n                        self.send(\"{}: {}\".format(message.get(\"sender\"), message.get(\"message\")), user.get(\"host\"), user.get(\"port\"))\r\n...\r\n<\/pre>\n<p>This class also extends <code>threading.Thread<\/code>. On initialization it will only require our queue and the user repository. In the <code>run<\/code> method, we just enter a <code>while True<\/code> and check if there is a message waiting in our queue. If there is any, it will pop one, get all connected users, and send the message it popped to every user that is not the sender. The send process is performed in a function called <code>send<\/code> that will open a socket, connect to the recipient endpoint and just send the text.<\/p>\n<p>Then, on a main method&#8230;<\/p>\n<p><span style=\"text-decoration: underline\"><em>messenger\/server\/messenger_server.py<\/em><\/span><\/p>\n<pre class=\"brush:python\">\r\ndef main():\r\n    queue = repository.Queue()\r\n    users = repository.Users()\r\n    host = input(\"host: \")\r\n    port = int(input(\"port: \"))\r\n    receiver = Receiver(host, port, queue, users)\r\n    sender = Sender(queue, users)\r\n    threads = [receiver.start(), sender.start()]\r\n<\/pre>\n<p>&#8230;we initialize our queue and users repository, ask for the endpoint to bind the server to, and just start our two threads. This code altogether looks like:<\/p>\n<p><span style=\"text-decoration: underline\"><em>messenger\/server\/messenger_server.py<\/em><\/span><\/p>\n<pre class=\"brush:python\">\r\nimport socket\r\nimport threading\r\nimport repository\r\n\r\nENCODING = 'utf-8'\r\n\r\n\r\nclass Receiver(threading.Thread):\r\n    def __init__(self, my_host, my_port, queue, users):\r\n        threading.Thread.__init__(self, name=\"messenger_receiver\")\r\n        self.host = my_host\r\n        self.port = my_port\r\n        self.queue = queue\r\n        self.users = users\r\n\r\n    def resolve_message(self, message):\r\n        if \"connect_request\" in message:\r\n            print(\"connect request received\")\r\n            arr = message.split(\"|\")\r\n            if len(arr) == 4:\r\n                user_name = arr[1]\r\n                user_host = arr[2]\r\n                user_port = arr[3]\r\n                print(\"adding user: {}, {}, {}\".format(user_name, user_host, user_port))\r\n                self.users.add_user(user_name, user_host, user_port)\r\n            else:\r\n                print(\"invalid connect request...\")\r\n        elif \"from:\" in message:\r\n            print(\"received message... starting queueing process\")\r\n            arr = message.split(\"|\")\r\n            if len(arr) == 2:\r\n                sender_name = arr[0].replace(\"from:\", \"\")\r\n                print(\"adding message from {} to queue\".format(sender_name))\r\n                message_text = arr[1]\r\n                self.queue.add_message(sender_name, message_text)\r\n\r\n    def run(self):\r\n        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n        sock.bind((self.host, self.port))\r\n        sock.listen(10)\r\n        while True:\r\n            connection, client_address = sock.accept()\r\n            print(\"connection received from {}\".format(str(client_address)))\r\n            try:\r\n                full_message = \"\"\r\n                while True:\r\n                    data = connection.recv(16)\r\n                    full_message = full_message + data.decode(ENCODING)\r\n                    if not data:\r\n                        print(\"received message: [{}]\".format(full_message))\r\n                        self.resolve_message(full_message.strip())\r\n                        break\r\n            finally:\r\n                print(\"exchange finished. closing connection\")\r\n                connection.shutdown(2)\r\n                connection.close()\r\n\r\n\r\nclass Sender(threading.Thread):\r\n\r\n    def __init__(self, queue, users):\r\n        threading.Thread.__init__(self, name=\"messenger_sender\")\r\n        self.queue = queue\r\n        self.users = users\r\n\r\n    def send(self, message, host, port):\r\n        print(\"sending message {} to {}\".format(message, str((host, port))))\r\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n        try:\r\n            s.connect((host, port))\r\n            s.sendall(message.encode(ENCODING))\r\n        finally:\r\n            print(\"message has been sent. closing connection\")\r\n            s.shutdown(2)\r\n            s.close()\r\n\r\n    def run(self):\r\n        while True:\r\n            if self.queue.messages_waiting():\r\n                print(\"there are messages on queue. popping one\")\r\n                message = self.queue.pop_message()\r\n                users = self.users.all_users()\r\n                for user in users:\r\n                    if user.get(\"name\") != message.get(\"sender\"):\r\n                        self.send(\"{}: {}\".format(message.get(\"sender\"), message.get(\"message\")), user.get(\"host\"), user.get(\"port\"))\r\n\r\n\r\ndef main():\r\n    queue = repository.Queue()\r\n    users = repository.Users()\r\n    host = input(\"host: \")\r\n    port = int(input(\"port: \"))\r\n    receiver = Receiver(host, port, queue, users)\r\n    sender = Sender(queue, users)\r\n    threads = [receiver.start(), sender.start()]\r\n\r\nif __name__ == '__main__':\r\n    main()\r\n<\/pre>\n<p>Now, the code of our client is pretty much the same as it was for our P2P messenger. For a client of this server, it will be transparent whether it is a room chat or a one on one conversation, and actually the old P2P messenger, connected to the server will work just as we want it to, but there will be no info on who was the sender of the message. Let&#8217;s look how it looks now:<\/p>\n<p><span style=\"text-decoration: underline\"><em>messenger\/client\/messenger_client.py<\/em><\/span><\/p>\n<pre class=\"brush:python\">\r\nimport socket\r\nimport threading\r\n\r\nENCODING = 'utf-8'\r\n\r\n\r\nclass Receiver(threading.Thread):\r\n\r\n    def __init__(self, my_host, my_port):\r\n        threading.Thread.__init__(self, name=\"messenger_receiver\")\r\n        self.host = my_host\r\n        self.port = my_port\r\n\r\n    def listen(self):\r\n        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n        sock.bind((self.host, self.port))\r\n        sock.listen(10)\r\n        while True:\r\n            connection, client_address = sock.accept()\r\n            try:\r\n                full_message = \"\"\r\n                while True:\r\n                    data = connection.recv(16)\r\n                    full_message = full_message + data.decode(ENCODING)\r\n                    if not data:\r\n                        print(full_message.strip())\r\n                        break\r\n            finally:\r\n                connection.shutdown(2)\r\n                connection.close()\r\n\r\n    def run(self):\r\n        self.listen()\r\n\r\n\r\nclass Sender(threading.Thread):\r\n\r\n    def __init__(self, server_host, server_port, user_name, local_host, local_port):\r\n        threading.Thread.__init__(self, name=\"messenger_sender\")\r\n        self.host = server_host\r\n        self.port = server_port\r\n        self.user_name = user_name\r\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n        s.connect((self.host, self.port))\r\n        s.sendall(\"connect_request|{}|{}|{}\".format(user_name, local_host, local_port).encode(ENCODING))\r\n        s.shutdown(2)\r\n        s.close()\r\n\r\n    def run(self):\r\n        while True:\r\n            message = input(\"\")\r\n            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n            s.connect((self.host, self.port))\r\n            s.sendall(\"from:{}|{}\".format(self.user_name, message).encode(ENCODING))\r\n            s.shutdown(2)\r\n            s.close()\r\n\r\n\r\ndef main():\r\n    my_host = input(\"host: \")\r\n    my_port = int(input(\"port: \"))\r\n    receiver = Receiver(my_host, my_port)\r\n    server_host = input(\"server host: \")\r\n    server_port = int(input(\"server port: \"))\r\n    user_name = input(\"user name: \")\r\n    sender = Sender(server_host, server_port, user_name, my_host, my_port)\r\n    treads = [receiver.start(), sender.start()]\r\n\r\n\r\nif __name__ == '__main__':\r\n    main()\r\n<\/pre>\n<p>Let&#8217;s see one by one the differences between our first example and the client of our chat room server:<\/p>\n<ul>\n<li>The prompts changed, as the endpoint we ask for is no longer your friend&#8217;s, but the server&#8217;s.<\/li>\n<li>We are now asking for a user name.<\/li>\n<li>The sender now receives both the endpoint from the remote server and the local one on initialization. Also, it receives the user name now.<\/li>\n<li>Also, on initialization, the <code>Sender<\/code> will send a message to the server for it to acknowledge the new user.<\/li>\n<li>Messages are now formatted as our standard defines.<\/li>\n<\/ul>\n<p>The rest looks the same, take your time reading the code, and make sure you understand every line. If you accomplish that goal, you will be able to use what you learnt here for any network related problem!<\/p>\n<p>Let&#8217;s have a look to our application working. Let&#8217;s start the server on a console and two clients on two independent consoles. Below is the output after the two clients connect and send a couple messages:<\/p>\n<p><span style=\"text-decoration: underline\"><em>server&#8217;s output<\/em><\/span><\/p>\n<pre class=\"brush:bash\">\r\nhost: localhost\r\nport: 8880\r\nconnection received from ('127.0.0.1', 44009)\r\nreceived message: [connect_request|first client|localhost|8881]\r\nconnect request received\r\nadding user: first client, localhost, 8881\r\nexchange finished. closing connection\r\nconnection received from ('127.0.0.1', 44010)\r\nreceived message: [connect_request|second client|localhost|8882]\r\nconnect request received\r\nadding user: second client, localhost, 8882\r\nexchange finished. closing connection\r\nconnection received from ('127.0.0.1', 44011)\r\nreceived message: [from:second client|HI!]\r\nreceived message... starting queueing process\r\nadding message from second client to queue\r\nexchange finished. closing connection\r\nthere are messages on queue. popping one\r\nsending message second client: HI! to ('localhost', 8881)\r\nmessage has been sent. closing connection\r\nconnection received from ('127.0.0.1', 44013)\r\nreceived message: [from:first client|Hi! Love this chat room!]\r\nreceived message... starting queueing process\r\nadding message from first client to queue\r\nexchange finished. closing connection\r\nthere are messages on queue. popping one\r\nsending message first client: Hi! Love this chat room! to ('localhost', 8882)\r\nmessage has been sent. closing connection\r\nconnection received from ('127.0.0.1', 44015)\r\nreceived message: [from:second client|Yeah! It's so simple. ]\r\nreceived message... starting queueing process\r\nadding message from second client to queue\r\nexchange finished. closing connection\r\nthere are messages on queue. popping one\r\nsending message second client: Yeah! It's so simple. to ('localhost', 8881)\r\nmessage has been sent. closing connection\r\nconnection received from ('127.0.0.1', 44017)\r\nreceived message: [from:first client|Python is the best!]\r\nreceived message... starting queueing process\r\nadding message from first client to queue\r\nexchange finished. closing connection\r\nthere are messages on queue. popping one\r\nsending message first client: Python is the best! to ('localhost', 8882)\r\nmessage has been sent. closing connection\r\n<\/pre>\n<p><span style=\"text-decoration: underline\"><em>first client&#8217;s output<\/em><\/span><\/p>\n<pre class=\"brush:bash\">\r\nhost: localhost\r\nport: 8881\r\nserver host: localhost\r\nserver port: 8880\r\nuser name: first client\r\nsecond client: HI!\r\nHi! Love this chat room!\r\nsecond client: Yeah! It's so simple.\r\nPython is the best!\r\n<\/pre>\n<p><span style=\"text-decoration: underline\"><em>second client&#8217;s output<\/em><\/span><\/p>\n<pre class=\"brush:bash\">\r\nhost: localhost\r\nport: 8882\r\nserver host: localhost\r\nserver port: 8880\r\nuser name: second client\r\nHI!\r\nfirst client: Hi! Love this chat room!\r\nYeah! It's so simple.\r\nfirst client: Python is the best!\r\n<\/pre>\n<p>Yes, that&#8217;s right, our chat room is working. Hurray! <\/p>\n<h2>3. Download the Code Project<\/h2>\n<p>This was a basic example on Network Programming with Python.<\/p>\n<div class=\"download\"><strong>Download<\/strong><br \/> You can download the full source code of this example here: <a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/03\/networking2.zip\"><strong>python-network-programming<\/strong><\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this example we&#8217;ll talk about Network Programming with Python. By using Python 3.4 and its powerful socket module, at the end of this example we&#8217;ll have a messenger working. First of all, let&#8217;s make it very clear. Sockets are behind any kind of network communications done by your computer. We all know that, when &hellip;<\/p>\n","protected":false},"author":109,"featured_media":1651,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[53],"tags":[343,344,323],"class_list":["post-11331","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python","tag-network-programming","tag-networking","tag-sockets"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Python Network Programming Tutorial - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"In this example we&#039;ll talk about Network Programming with Python. By using Python 3.4 and its powerful socket module, at the end of this example we&#039;ll\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Python Network Programming Tutorial - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"In this example we&#039;ll talk about Network Programming with Python. By using Python 3.4 and its powerful socket module, at the end of this example we&#039;ll\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/sgvinci\" \/>\n<meta property=\"article:published_time\" content=\"2016-03-09T14:15:57+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-01-09T07:44:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Sebastian Vinci\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@sebastianvinci_\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sebastian Vinci\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/\"},\"author\":{\"name\":\"Sebastian Vinci\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/06a43c63e373dff2e159bbc029b405aa\"},\"headline\":\"Python Network Programming Tutorial\",\"datePublished\":\"2016-03-09T14:15:57+00:00\",\"dateModified\":\"2018-01-09T07:44:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/\"},\"wordCount\":2364,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"keywords\":[\"network programming\",\"networking\",\"sockets\"],\"articleSection\":[\"Python\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/\",\"name\":\"Python Network Programming Tutorial - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"datePublished\":\"2016-03-09T14:15:57+00:00\",\"dateModified\":\"2018-01-09T07:44:29+00:00\",\"description\":\"In this example we'll talk about Network Programming with Python. By using Python 3.4 and its powerful socket module, at the end of this example we'll\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Python\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/python\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Python Network Programming Tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/06a43c63e373dff2e159bbc029b405aa\",\"name\":\"Sebastian Vinci\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/12d0233b49dd2a282330a987b16e81c3fbd4a8a8f5d5338348a6edd47cfff99e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/12d0233b49dd2a282330a987b16e81c3fbd4a8a8f5d5338348a6edd47cfff99e?s=96&d=mm&r=g\",\"caption\":\"Sebastian Vinci\"},\"description\":\"Sebastian is a full stack programmer, who has strong experience in Java and Scala enterprise web applications. He is currently studying Computers Science in UBA (University of Buenos Aires) and working a full time job at a .com company as a Semi-Senior developer, involving architectural design, implementation and monitoring. He also worked in automating processes (such as data base backups, building, deploying and monitoring applications).\",\"sameAs\":[\"http:\/\/www.webcodegeeks.com\/\",\"https:\/\/www.facebook.com\/sgvinci\",\"https:\/\/x.com\/sebastianvinci_\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/sebastian-vinci\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Python Network Programming Tutorial - Web Code Geeks - 2026","description":"In this example we'll talk about Network Programming with Python. By using Python 3.4 and its powerful socket module, at the end of this example we'll","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/","og_locale":"en_US","og_type":"article","og_title":"Python Network Programming Tutorial - Web Code Geeks - 2026","og_description":"In this example we'll talk about Network Programming with Python. By using Python 3.4 and its powerful socket module, at the end of this example we'll","og_url":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_author":"https:\/\/www.facebook.com\/sgvinci","article_published_time":"2016-03-09T14:15:57+00:00","article_modified_time":"2018-01-09T07:44:29+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","type":"image\/jpeg"}],"author":"Sebastian Vinci","twitter_card":"summary_large_image","twitter_creator":"@sebastianvinci_","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Sebastian Vinci","Est. reading time":"21 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/"},"author":{"name":"Sebastian Vinci","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/06a43c63e373dff2e159bbc029b405aa"},"headline":"Python Network Programming Tutorial","datePublished":"2016-03-09T14:15:57+00:00","dateModified":"2018-01-09T07:44:29+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/"},"wordCount":2364,"commentCount":1,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","keywords":["network programming","networking","sockets"],"articleSection":["Python"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/","url":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/","name":"Python Network Programming Tutorial - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","datePublished":"2016-03-09T14:15:57+00:00","dateModified":"2018-01-09T07:44:29+00:00","description":"In this example we'll talk about Network Programming with Python. By using Python 3.4 and its powerful socket module, at the end of this example we'll","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/python\/python-network-programming-tutorial\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Python","item":"https:\/\/www.webcodegeeks.com\/category\/python\/"},{"@type":"ListItem","position":3,"name":"Python Network Programming Tutorial"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/06a43c63e373dff2e159bbc029b405aa","name":"Sebastian Vinci","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/12d0233b49dd2a282330a987b16e81c3fbd4a8a8f5d5338348a6edd47cfff99e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/12d0233b49dd2a282330a987b16e81c3fbd4a8a8f5d5338348a6edd47cfff99e?s=96&d=mm&r=g","caption":"Sebastian Vinci"},"description":"Sebastian is a full stack programmer, who has strong experience in Java and Scala enterprise web applications. He is currently studying Computers Science in UBA (University of Buenos Aires) and working a full time job at a .com company as a Semi-Senior developer, involving architectural design, implementation and monitoring. He also worked in automating processes (such as data base backups, building, deploying and monitoring applications).","sameAs":["http:\/\/www.webcodegeeks.com\/","https:\/\/www.facebook.com\/sgvinci","https:\/\/x.com\/sebastianvinci_"],"url":"https:\/\/www.webcodegeeks.com\/author\/sebastian-vinci\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/11331","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/109"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=11331"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/11331\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/1651"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=11331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=11331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=11331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}