Socket Programming in Python: Client, Server, Peer | PubNub

Socket programming is the implementation of two sockets to send and receive data bi-directionally at any given moment. It connects two sockets (or nodes) together and allows them to communicate in real time. Internet-connected applications that need to operate in real time greatly benefit from the implementation of sockets in their networking code, allowing data to be sent and received at any time.

About Python sockets

In this Python socket tutorial, you’ll learn how to send data from client-to-server and client-to-client connections using socket programming in Python. You’ll also learn how you can leverage the power of PubNub to send data between two or more client devices for peer-to-peer communication using the PubNub Python SDK. Although this Python socket tutorial guides you step-by-step through this process, you can view a video walkthrough of this tutorial on YouTube and find the source code for this application in the GitHub repository.

Socket programming in Python: Environment Set up

In this section, you will install the necessary tools and dependencies to be able to utilize Python sockets and PubNub.

Setup your free PubNub account for socket programming in Python

You’ll need to create a free PubNub account, as you’ll need your publish/subscribe keys to send information across the PubNub Network. You can learn how to create your keys in this video/written walkthrough.

Ensure that you enable Presence to know when users come online and Message Persistence to persist information passed between clients. Copy the publish and subscribe keys to a text editor, as you’ll need these later on.

Download the latest Python programming language

You’ll need to download the latest version of the Python programming language, which in this case is 2.7.x. Download the latest stable release of Python 2.x from the official website. Ensure Python is added to PATH when installing.

Get a code editor for socket programming in Python

You will need to download and use your favorite code editor when developing this Python socket application. Visual Studio Code is recommended as it is a lightweight, open-source, and free code editor that supports different languages and frameworks. You are welcome to add any popular extensions for Python to help with intellisense and debugging.

Build and run your Python socket application

Now it’s time to finally start building the example socket application in Python. Natively, Python provides a socket class so developers can perform Python socket programming without needing to use a socket API. Begin by setting up the Python socket client and server.

Python socket Client-Server

python socket connection diagram

Create the file client.py in the project directory. To use a socket object in the program, import the Python socket library that comes natively. You’ll then create a new socket object that connects to a specified IP address (in this case localhost’s port number 8080) to create a new connection to the socket server (that will be created shortly in server.py). You can then send information to the server and close the client socket server connection once you are done.

Open the client.py file in Visual Studio Code and add the following code that functions exactly as described previously.

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

You’ll need to set up the socket server to listen for any incoming connections and information from the client. Create the file server.py in the project directory. Add the following code to the file.

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'

The server binds the socket object to localhost’s 8080 port as the socket server for the client to connect. When clients connect to this address with a socket connection, the server will accept connections if there is a valid connection and stores data. If the server properly receives information from the client, it will send a confirmation string back to the client.

To test this out yourself, open two terminal windows at the same time, as you will need to run the python files using the python .py command, replacing filename with the names of the files. Run the server program server.py in one terminal window and then run the client program client.py file in the other. The client-side program will send the “I am CLIENT” string to the server that is currently waiting for a reply. The server-side Python program will process, store, and send back a response to the client.

Client-to-Client Python socket programming

Although the basic functionality of sending data client-to-server is working correctly, sending data between two or more devices 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 socket code that you implemented will not be 100% reliable for sending peer-to-peer data in the application, considering that the socket server in Python needs to be constantly running for information to be received.

This is where PubNub comes in. PubNub is a developer API platform that powers the real-time infrastructure in apps to build engaging Virtual Spaces where online communities can truly connect. With One-to-Many, One-to-One, or Many-to-Many, PubNub scales automatically to support any application load. Using PubNub’s real-time data APIs opens up an instant, always-on connection between all clients that have the publish/subscribe API keys. This accomplishes the same objectives as a socket connection without needing to manage the infrastructure yourself.

To integrate PubNub into the project, install the PubNub package with pip in the terminal. This will allow you to use the PubNub Python SDK and communicate on the PubNub network.

pip install 'pubnub>=7.0.2'

Since you already have the PubNub API keys, you’ll implement two separate clients that run on the PubNub network. Create a file pn_client_1.py and add the following code. Replace your publish and subscribe keys in the pnconfig.publish_key and pnconfig.subscribe_key sections.

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 = 'enter your pubnub publish key here'
pnconfig.subscribe_key = 'enter 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)

Create the file pn_client_2.py and add the following code. Replace your publish and subscribe keys in the pnconfig.publish_key and pnconfig.subscribe_key fields.

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 = 'enter your pubnub publish key here'
pnconfig.subscribe_key = 'enter 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)

As was performed earlier for the client-to-server socket connection, open two terminal windows at the same time, as you will need to run the pn_client python files using the python .py command, replacing filename with the pn_client python files. Each file represents a client that can communicate with each other by sending text messages in the terminal.

Each client initializes its connection to the PubNub network with the publish and subscribe keys and connects to the chan-1 channel. You can think of this as sending data over a TCP server socket in Python. Whenever a client sends a message, the other client is listening using an event listener to process the information and display the message in their own terminal.

Python socket programming: What’s next?

Congratulations, you have learned how to set up a basic client-to-server socket in Python, as well as use PubNub to serve as the infrastructure to power the connection of client-to-client communication.

You can watch a video walkthrough of this tutorial on YouTube and view the completed version of the application on GitHub. If you would like to learn more about how to power your applications with PubNub, be sure to check out PubNub’s other developer resources:

  • Explore PubNub’s core features in a live coding tour.

  • Interact with working demos that utilize PubNub’s network connection.

  • Understand key concepts when building with PubNub.

  • Build different industry applications with PubNub with step-by-step tutorials.

If you’d like to learn more about PubNub, then click here for a free demo.