IN THIS ARTICLE
Full source code repository on GitHubGitHub Repo
This tutorial walks through how you can send data from device-to-device, client-to-server, and vice versa using socket programming in Python.
More of a visual learner? Check out our socket programming in python video tutorial below.
Ready to build? Let's jump in!
What is Socket Programming?
Sockets (aka socket programming) is a program that enables two sockets to send and receive data, bi-directionally, at any given moment.
It works by connecting two sockets (or nodes) together and allowing them to communicate in real time, and is a great option for building a myriad of apps.
Why Use Sockets to Send Data?
Internet-connected applications that need to operate in realtime greatly benefit from the implementation of sockets in their networking code. Some examples of apps that use socket programming are:
- Web pages that show live notifications (Facebook, Twitch, eBay)
- Multiplayer online games (League of Legends, WoW, Counter Strike)
- Chat apps (WhatsApp, WeChat, Slack)
- Realtime data dashboards (Robinhood, Coinbase)
- IoT devices (Nest, August Locks)
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 threads can handle the new socket data. Libraries like asyncio implement multiple threads, so your Python program can work in an asynchronous fashion.
Python Socket Programming Tutorial
Natively, Python provides a socket class so developers can easily implement socket objects in their source code. We can start implementing sockets in our progam with three simple steps:
Import Socket Library
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.
Build Socket Objects
Now we can create socket objects in our code.
Open and Close Connection
Once we have an initialized socket object, we can use some methods to open a connection, send data, receive data, and finally close the connection.
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 Address Format Internet.
The type parameter is set to Socket Stream, also the default which enables “sequenced, reliable, two-way, connection-based byte streams” over TCP1.
## 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()
Python Socket Client Server
Now that we know a few methods for transmitting bytes, let’s create a client and server program with 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
") conn.close() print 'client disconnected'
How Does it Work?
This code makes a socket object, and binds it to localhost’s port 8080 as a socket server. When clients connect to this address with a socket connection, the server listens for data, and stores it in the “data” variable.
Then, the program logs the client data using “print,” and then sends a string to the client: I am SERVER.
Let’s take a look at client code that would interact with this server program.
Python Socket Client
Here is the client socket demo code.
import socket client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(('0.0.0.0', 8080)) client.send("I am CLIENT
") from_server = client.recv(4096) client.close() print from_server
How Does it Work?
This client opens up a socket connection with the server, but only if the server program is currently running. To test this out yourself, you will need to use 2 terminal windows at the same time.
Next, the client sends some data to the server: I am CLIENT
Then the client receives some data it anticipates from the server.
Done! You can now get started streaming data between clients and servers using some basic Python network programming.
How Do You Send Data Between Clients?
Sending data between 2 or more client 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 code that we implemented will not be 100% reliable for sending peer-to-peer data in our realtime app.
So, how do we achieve reliability and speed when transmitting peer-to-peer data?
This can be accomplished using a server in the middle:
- 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.
PubNub does this best with the Pub/Sub API. It is fast, reliable, secure, and easy to implement on any client device.
With One-to-Many, One-to-One, or Many-to-Many, PubNub scales automatically 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.
PubNub and Python with an SSL Connection
Here is an example of peer-to-peer data that is sent with PubNub, on a single channel, with SSL. 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 infinite number of channels to send messages in realtime. Before you try the code, be sure to make a free PubNub account.
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)
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!
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)
Wrapping Up Socket Programming in Python
All of the code in this post is hosted on GitHub in the Python Socket Demo repository, if you'd like to have it all in one place.
We hope you enjoy using our guide to socket programming. Hopefully you can use it to build something amazing. It could be an amazing smart home security system, or a realtime chat app! The possibilities are endless. Let us know what you create!