Socket Programming in Python: Client, Server, and Peer Examples
Tags: python, pubnub, socket
Published: 2019-07-17 00:06:28

---
title: Socket Programming in Python: Client, Server, and Peer Examples
published: true
description: Sockets (aka socket programming) enable programs to send and receive data, bi-directionally, at any given moment. This tutorial walks through how you can send data from device-to-device, client-to-server, and vice versa using socket programming in Python. 
tags: Python, PubNub, Socket
canonical: https://www.pubnub.com/blog/socket-programming-in-python-client-server-p2p/
---

Sockets (aka socket programming) enable programs to send and receive data, <strong>bi-directionally</strong>, at any given moment. This tutorial walks through how you can <strong>send data</strong> from <strong>device-to-device</strong>, <strong>client-to-server</strong>, and <strong>vice versa</strong> using socket programming in <a href="https://www.python.org/">Python</a>.

{% youtube 6sHGBXwkFQU %}

<h2>Why use sockets to send data?</h2>
Internet-connected applications that need to operate in realtime greatly benefit from the implementation of <strong>sockets</strong> in their <strong>networking code</strong>. Some examples of apps that use socket programming are:
<ul>
 	<li>Web pages that show <a href="https://www.pubnub.com/solutions/realtime-updates/?utm_source=Syndication&utm_medium=DevTo&utm_campaign=SYN-CY19-Q3-DevTo-Jul-16">live notifications</a> (Facebook, Twitch, eBay)</li>
 	<li><a href="https://www.pubnub.com/solutions/multiplayer-games/?utm_source=Syndication&utm_medium=DevTo&utm_campaign=SYN-CY19-Q3-DevTo-Jul-16">Multiplayer online games</a> (League of Legends, WoW, Counter Strike)</li>
 	<li><a href="https://www.pubnub.com/solutions/chat/?utm_source=Syndication&utm_medium=DevTo&utm_campaign=SYN-CY19-Q3-DevTo-Jul-16">Chat apps</a> (WhatsApp, WeChat, Slack)</li>
 	<li><a href="https://www.pubnub.com/solutions/realtime-dashboards/?utm_source=Syndication&utm_medium=DevTo&utm_campaign=SYN-CY19-Q3-DevTo-Jul-16">Realtime data dashboards</a> (Robinhood, Coinbase)</li>
 	<li><a href="https://www.pubnub.com/solutions/iot/?utm_source=Syndication&utm_medium=DevTo&utm_campaign=SYN-CY19-Q3-DevTo-Jul-16">IoT devices</a> (Nest, August Locks)</li>
</ul>
Python, unlike JavaScript, is a language that executes <a href="https://hackernoon.com/javascript-promises-and-why-async-await-wins-the-battle-4fc9d15d509f" target="_blank" rel="noopener noreferrer">synchronously</a>. This is why <strong>asyncio</strong> was developed - to make Python more robust, particularly for the nature of socket programming.

With streaming sockets, data can be sent or received at any time. In case your Python program is in the middle of executing some code, other <strong>threads</strong> can handle the new socket data. Libraries like <a href="https://docs.python.org/3/library/asyncio.html" target="_blank" rel="noopener noreferrer">asyncio</a> implement multiple threads, so your Python program can work in an asynchronous fashion.
<h2>Python Socket Programming Tutorial</h2>
Natively, Python provides a <a href="https://docs.python.org/3/library/socket.html" target="_blank" rel="noopener noreferrer">socket class</a> so developers can easily implement <strong>socket objects</strong> in their source code. To use a socket object in your program, start off by importing the socket library. No need to install it with a package manager, it comes out of the box with Python.
```python
import socket
```
Now we can create socket objects in our code.
```python
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
```
This code creates a socket object that we are storing in the "sock" variable. The constructor is provided a family and type parameter respectively.  The family parameter is set to the default value, which is the <strong>Address Format Internet</strong>.

The type parameter is set to <strong>Socket Stream</strong>, also the default which enables "sequenced, reliable, two-way, connection-based byte streams" over <strong>TCP</strong><a href="http://man7.org/linux/man-pages/man2/socket.2.html"><sup>1</sup></a>.

Once we have an initialized socket object, we can use some methods to open a <strong>connection</strong>, <strong>send</strong> data, <strong>receive</strong> data, and finally <strong>close</strong> the connection.
```python
## Connect to an IP with Port, could be a URL
sock.connect(('0.0.0.0', 8080))

## Send some data, this method can be called multiple times
sock.send("Twenty-five bytes to send")

## Receive up to 4096 bytes from a peer
sock.recv(4096)

## Close the socket connection, no more data transmission
sock.close()
```
<h2>Python Socket Server</h2>
Now that we know a few methods for transmitting bytes, let's create a client and server program with Python.
```python
import socket

serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

serv.bind(('0.0.0.0', 8080))
serv.listen(5)

while True:
    conn, addr = serv.accept()
    from_client = ''

    while True:
        data = conn.recv(4096)
        if not data: break
        from_client += data
        print from_client

        conn.send("I am SERVER\n")

    conn.close()
    print 'client disconnected'
```
This code makes a socket object, and binds it to <strong>localhost's port 8080</strong> as a <strong>socket server</strong>. When clients connect to this address with a socket connection, the server listens for data, and stores it in the "data" variable.

Next, the program logs the client data using "print," and then sends a string to the client: <strong>I am SERVER</strong>.

<img class="wp-image-39138 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/01/python-socket-connection-diagram.png" alt="Python Socket Programming Diagram" width="748" height="353" />

Let's take a look at client code that would interact with this server program.
<h2>Python Socket Client</h2>
Here is the <strong>client</strong> socket demo code.
```python
import socket

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('0.0.0.0', 8080))

client.send("I am CLIENT\n")

from_server = client.recv(4096)

client.close()

print from_server
```
This client opens up a socket connection with the server, but <strong>only if the server program is currently running</strong>. To test this out yourself, you will need to use <strong>2 terminal windows</strong> at the same time.

Next, the client sends some data to the server: <strong>I am CLIENT</strong>

Then the client receives some data it anticipates from the server.

Done! You can now get started <strong>streaming data between clients and servers</strong> using some basic Python network programming.
<h2>How Do You Send Data Between Clients?</h2>
Sending data <strong>between 2 or more client devices</strong> over the internet is tricky. Due to protections implemented by network security, not all devices connected to the world wide web have a publicly accessible internet protocol (IP) address.

This means that the Python code that we implemented will not be 100% reliable for sending peer-to-peer data in our realtime app. How do we achieve <strong>reliability</strong> and <strong>speed</strong> when transmitting <strong>peer-to-peer data</strong>?

This can be accomplished using a <strong>server in the middle</strong>. Client devices using the internet can connect to a server with a public IP address (or a website domain). Then, this broker in the middle can pass messages routed to 1 or many clients.

<img class="wp-image-39129 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/01/pubsub-diagram.png" alt="PubNub Pub/Sub Diagram" width="569" height="380" />

PubNub does this best with the <a href="https://www.pubnub.com/products/realtime-messaging/?utm_source=Syndication&utm_medium=DevTo&utm_campaign=SYN-CY19-Q3-DevTo-Jul-16"><strong>Pub/Sub API</strong>.</a> It is fast, reliable, secure, and easy to implement on <strong>any client device</strong>. Whether you have a Python server, a JavaScript website, or anything in between, you can use PubNub to send data to anyone in <strong>under 250ms</strong>.

With <strong>One-to-Many</strong>, <strong>One-to-One</strong>, or <strong>Many-to-Many</strong>, PubNub <strong>scales automatically</strong> to support any application load. Using the API opens up an instant, always-on connection between all clients that have the Pub/Sub API keys. This accomplishes the same objectives as a socket connection.
<h2>PubNub and Python with an SSL Connection</h2>
Here is an example of <strong>peer-to-peer data</strong> that is sent with PubNub, on a single channel, with <strong>SSL</strong>. You can think of this like sending data over a TCP socket. When you sign up for a free PubNub account, you can use a practically <strong>infinite number of channels</strong> to send messages in realtime. Before you try the code, be sure to <a href="https://dashboard.pubnub.com/signup/?utm_source=Syndication&utm_medium=DevTo&utm_campaign=SYN-CY19-Q3-DevTo-Jul-16"<strong>make a free PubNub account</strong>.

<h3>Client 1</h3>
```python
from pubnub.callbacks import SubscribeCallback
from pubnub.enums import PNStatusCategory
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
import time
import os

pnconfig = PNConfiguration()

pnconfig.publish_key = 'your pubnub publish key here'
pnconfig.subscribe_key = 'your pubnub subscribe key here'
pnconfig.ssl = True

pubnub = PubNub(pnconfig)

def my_publish_callback(envelope, status):
    # Check whether request successfully completed or not
    if not status.is_error():
        pass

class MySubscribeCallback(SubscribeCallback):
    def presence(self, pubnub, presence):
        pass
    def status(self, pubnub, status):
        pass
    def message(self, pubnub, message):
        print "from device 2: " + message.message

pubnub.add_listener(MySubscribeCallback())
pubnub.subscribe().channels("chan-1").execute()

## publish a message
while True:
    msg = raw_input("Input a message to publish: ")
    if msg == 'exit': os._exit(1)
    pubnub.publish().channel("chan-1").message(str(msg)).pn_async(my_publish_callback)
```
<h3>Client 2</h3>
Strings can be entered on the command line for these 2 client programs. Maximum message size for PubNub publishing is 32kb. Use 2 terminal windows to try out the code!
```python
from pubnub.callbacks import SubscribeCallback
from pubnub.enums import PNStatusCategory
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
import time
import os

pnconfig = PNConfiguration()

pnconfig.publish_key = 'your pubnub publish key here'
pnconfig.subscribe_key = 'your pubnub subscribe key here'
pnconfig.ssl = True

pubnub = PubNub(pnconfig)

def my_publish_callback(envelope, status):
    # Check whether request successfully completed or not
    if not status.is_error():
        pass

class MySubscribeCallback(SubscribeCallback):
    def presence(self, pubnub, presence):
        pass
    def status(self, pubnub, status):
        pass
    def message(self, pubnub, message):
        print "from device 1: " + message.message

pubnub.add_listener(MySubscribeCallback())
pubnub.subscribe().channels("chan-1").execute()

## publish a message
while True:
    msg = raw_input("Input a message to publish: ")
    if msg == 'exit': os._exit(1)
    pubnub.publish().channel("chan-1").message(str(msg)).pn_async(my_publish_callback)
```
All of the code in this post is hosted on <a href="https://github.com/ajb413/python-socket-demo" target="_blank" rel="noopener noreferrer">GitHub in the Python Socket Demo repository</a>.

PubNub is entirely free up to <strong>1 million messages per month</strong>. For more capability of the API, check out the <a href="https://www.pubnub.com/docs/python/pubnub-python-sdk?utm_source=Syndication&utm_medium=DevTo&utm_campaign=SYN-CY19-Q3-DevTo-Jul-16">PubNub Python v4 SDK documentation</a>, or any of the other <a href="https://www.pubnub.com/developers/?utm_source=Syndication&utm_medium=DevTo&utm_campaign=SYN-CY19-Q3-DevTo-Jul-16">75+ PubNub client SDKs</a>.