Sockets are used to transmit messages between devices over local or global networks. Socket is an endpoint of communication and this is why sockets are helpful in real-time client-server applications that depend on instant message exchange, such as WhatsApp.
What Is Socket Programming?
Socket programming is a means of communication between nodes over a network. Nodes can refer to clients and servers. A server is a software program that waits for client requests and serves the incoming processes, while a client is the requester of the services. A client requests resources from the server and the server responds to the request.
For instance: To read this article, your browser establishes a socket connection to the Builtin.com website server and sends a request message to the server, requesting this article. The server then sends the blog to your browser over the socket connection. Here, sockets help to establish a connection between your browser and the website server.
In this article, you will learn about socket programming in Python. You will learn how to create socket-based client and server applications using Python.
What Is Socket Programming?
Socket programming is a means of communication between nodes over a network. Nodes can refer to clients and servers. A server is a software program that waits for client requests and serves the incoming processes, while a client is a requester of the service. A client requests resources from the server, and the server responds to the request.
To establish a connection between a client and a server, we create a socket in each program and then connect both sockets together. Once the socket connection is established, the nodes can exchange data.
Socket() Module in Python
In Python, the socket module provides a way to work with sockets. As we discussed earlier, sockets allow you to establish network connections over various network protocols such as TCP or UDP to send and receive data. To use it in your code, you first need to import the socket module.
Once you have imported the module, you can use the socket()
method to create a socket object. Below are some of the important methods of socket module.
Understanding the Client-Server Model
In the previous sections, you learned that the client requests some resources from the socket server and the server responds to that request. In this section, you will learn how to code both the server and the client so that they can easily communicate with each other.
Python Socket Server
Python socket server executes first and then waits for any request from clients. The server has the bind()
method which binds the IP address and Port number so that it can listen to incoming requests from the client on that IP and Port. In the bind method, instead of IP, if we pass the empty string, then this makes the server listen to requests coming from other computers on the network.
Next, the server has the listen()
method, which puts the server in listening mode so that it can listen to incoming connections. Lastly, the server has an accept()
method that initiates a connection with the client, and lastly, the close()
method that closes the connection with the client.
So the sequence is: bind, listen, accept, communicate, close.
Python Socket Client
Python socket client program will initiate the conversation at first. This is very similar to the Python socket server. The only difference is that in the server program, we use the bind()
method to bind the host address and port address, but in the client program we use the connect()
method to connect the host address and port address so that it can connect to the server easily and communicate with it.
Examples of Code for Python Socket Programming
We have discussed the theory of Python socket programming. It is time to write some code to develop client and server sockets. Note: Run the server script first and then the client script.
Creating a Server Socket
To create a server socket, follow these steps:
- Import the socket module.
- Get the hostname using the
socket.gethostname()
method. This is optional because you can also pass the empty string, which means the server can listen to connections coming from other computers. - Specify a port to listen on, keeping in mind that the port number should be greater than 1024. In this example, the port number is 21042.
- Create a socket object using the
socket.socket()
method. - Bind the host and the port number using the
bind()
method. - Call the
listen()
method, you can configure how many clients the server can listen to simultaneously. - Establish a connection with the client using the
accept()
method. - Send the message to the client using the
send()
method. - Close the connection with the client using the
close()
method.
import socket
def server():
# Get the hostname of the server
host = socket.gethostname()
# Specify the port to listen on
port = 21042
# Create a socket object
s = socket.socket()
# Bind the socket to the host and port
s.bind((host, port))
# Listen for incoming connections, allowing up to 2 clients in the queue
s.listen(2)
# Accept an incoming connection
c, address = s.accept()
print(f"Connected to: {address}")
while True:
# Receive data from the client (up to 1024 bytes) and decode it
data = c.recv(1024).decode()
# If no data is received, break the loop
if not data:
break
print(f"Received from client: {data}")
# Get user input and send it to the client after encoding
response = input("Enter response to send to client: ")
c.send(response.encode())
# Close the client connection
c.close()
if __name__ == "__main__":
# Start the server
server()
What’s happening in the above code?
First, we import the socket module. Then, we create a socket object and bind it to the hostname and port number. This means that the server will only listen for connections that are bound to that particular hostname and port number.
Next, we put the server into listening mode. You might be wondering what the 2
in the listen()
method call means. This is the maximum number of connections that the operating system can queue for this socket. In other words, two connections can be in the socket’s queue at any given time. If there are more than two incoming connections, the kernel will reject them.
Creating a Client Socket
To create a client socket, follow these steps.
- Import the socket module.
- (Optional) Get the hostname using the
socket.gethostname()
method. - Create a socket object using the
socket.socket()
method. - Connect to the local host by passing the port number and hostname of the server. In this example, the port number is 21042.
- Send and receive messages from the server using the
send()
andrecv()
methods. - Close the connection with the server.
# Import the socket module
import socket
def client():
# Get the host name (as both server and client code are running on your PC)
host = socket.gethostname()
# Define the server's port number to interact with
port = 21042
# Create a socket object
client_socket = socket.socket()
# Connect to the server by specifying the hostname and port number
client_socket.connect((host, port))
# Prompt the user for input
message = input("Enter your message (Type 'bye' to exit): ")
while message.lower().strip() != "bye":
# Send the message to the server
client_socket.send(message.encode())
# Receive a response from the server
data = client_socket.recv(1024).decode()
# Display the received message from the server
print("Received from server: " + data)
# Prompt for the next message
message = input("Enter your message (Type 'bye' to exit): ")
# Close the connection
client_socket.close()
if __name__ == "__main__":
client()
What’s happening in the above code?
As you can see in the above code, we first create a socket object, then connect to localhost on port 21042, and then receive data from the server, send data to the server, and close the connection.
To see the output, first run the socket server program. Then, run the socket client program. After that, write something from the client program. Then, again write a reply from the server program. Finally, write “bye” from the client program to terminate both programs.
Error Handling in Python Socket Programming
Error handling is important in socket programming because you might have to deal with many types of errors, such as connection failures, timeouts, incorrect socket parameters and data transmission issues. To handle these errors, use try-except blocks to catch the errors easily. Let’s add some error handling to the server socket code.
import socket
def server():
try:
host = socket.gethostname()
port = 21042
s = socket.socket()
s.bind((host, port))
s.listen(2)
c, address = s.accept()
print(f"Connected to: {address}")
while True:
data = c.recv(1024).decode()
if not data:
break
print(f"Received from client: {data}")
response = input("Enter response to send to client: ")
c.send(response.encode())
except Exception as e:
print(f"Error: {e}")
finally:
c.close()
if __name__ == "__main__":
server()
The Exception class will catch all the socket-related exceptions, such as socket.error, ConnectionError, and TimeoutError and handle them easily. The finally block will be executed even if an exception occurs in the try block, so we have put the close() method
in the finally block.
Frequently Asked Questions
What are Python sockets used for?
Sockets establish network connections over various network protocols such as TCP or UDP to send and receive data. Therefore, a socket is an endpoint of communication.
What do server sockets do?
A server socket listens and accepts connections from client sockets. Once a connection is established, the server socket can send and receive data with the client socket.
What are the alternatives to sockets in Python?
Some popular alternatives to sockets in Python include:
asyncio: Provides a high-level interface for asynchronous programming.
WebSocket: A library for building WebSocket servers and clients in Python.
SignalR: A library for adding real-time functionality to ASP.NET applications.