Socket Programming in Python: A Beginners Guide

Aditya Raj Oct 10, 2023
  1. How to Implement Socket Programming in Python
  2. How to Create a Server in Socket Programming in Python
  3. Socket Programming With the UDP Protocol in Python
  4. Conclusion
Socket Programming in Python: A Beginners Guide

Normally, when we write a program, we don’t need to communicate with other programs or computers.

However, we might need to communicate with other computers to create messenger or other applications with server-client architecture. For creating such applications, we can use socket programming in Python.

This article will discuss the basics of socket programming in Python. We will also separately implement a simple messenger application using socket programming with TCP and UDP protocols.

What Are Sockets in Python

When two applications or processes interact, they use a specified communication channel. Sockets are the endpoints or entry points of such communication channels.

We can use sockets to establish a communication channel between two processes, within a process or between processes on different machines. There are different types of sockets like TCP sockets, UDP sockets, and UNIX domain sockets.

How to Implement Socket Programming in Python

Python provides us with the socket module to implement socket programming. The socket module is part of the standard Python library, and it provides all the functions and methods with the help of which you can create sockets in Python.

You don’t need to download the socket module in your machine explicitly, and you can directly import it into your program using the import statement as follows.

import socket

To implement socket programming, we need to create two processes that will communicate using the socket.

One of the programs works as a server, and the other works as a client. Both the server and client have different functionalities. Hence we use different functions while creating server and client processes.

Let us discuss how to create a server and a client process one by one.

How to Create a Server in Socket Programming in Python

To create a server, we will first create a socket. For this, we use the socket() method.

Create a Socket: The socket() Method

The syntax for the socket() method is as follows.

socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None)

Here,

  • The parameter family represents the address family to which a socket belongs. By default, it is AF_INET and creates a socket with an Internet protocol version 4 (IPv4) address. You can use other address families like AF_UNIX for the UNIX address and AF_INET6 for the internet protocol version 6 (IPv6) address.
  • The parameter type denotes the socket type. By default, it has the value SOCK_STREAM denoting that the socket will follow connection-oriented TCP protocol. You can use SOCK_DGRAM to create datagram sockets that follow UDP protocol.
  • The parameter proto denotes the protocol number, and it is usually 0. If you use the address family AF_CAN in the parameter family, the protocol number should be one of CAN_RAW, CAN_BCM, CAN_ISOTP, or CAN_J1939.
  • The parameter fileno contains the default value None. If we specify a file descriptor in fileno, the values for the parameters family, type, and proto are automatically detected from the file descriptor.

After creating a socket, we bind it to an address and a port number using the bind() method.

Bind the Socket to an Address: The bind() Method

Using the socket() function, the bind() method is invoked on the socket object that we created.

It takes a tuple containing the address to which the socket will be bound. The format of the address may vary depending on the address family you have chosen. We will create a socket with the address family AF_INET. Hence, the address will contain the hostname and the port number.

The syntax for the bind() method is as follows.

bind((hostname, port))

You can specify the hostname explicitly. If you create the server on the local machine, you can specify the hostname as localhost or 127.0.0.1, the default value for the localhost address.

Alternatively, you can use the gethostname() method to get the hostname. For the parameter port, you can use any port number above 1024 and less than 65535.

After binding the socket to an address, the server listens to the client’s connection requests. For this, we use the listen() method.

Listen for the Connections: The listen() Method

The syntax for the listen() method is as follows.

listen(backlog)

Here, the parameter backlog denotes the maximum number of unaccepted connections the system will allow before refusing new connections.

After executing the listen() method, the server becomes ready to accept connections.

Accept a Connection Request: The accept() Method

The server constantly runs in an infinite loop and listens for client requests to accept a connection from a client. Once a client request is found, The server accepts the request using the accept() method.

The accept() method returns a tuple (client, address). Here, client represents a new socket object that we use to send and receive messages. The address is where the client socket is bound.

Communicating With the Client: send() and recv() Methods

After accepting the connection, the server can communicate with the client.

We use the send() method to send a message to the client. The send() method is invoked on the client object returned by the accept() method.

We use the recv() method to receive the messages. The recv() method, when invoked on the client object, accepts a number representing the maximum number of bytes it can read from the connection. After execution, it returns the data read from the connection.

After all the operations are completed, we need to close the connection. For this, we invoke the close() method on the client object returned by the accept() method.

Having discussed all the methods required to create a server, let us create a server process.

import socket

mySocket = socket.socket(
    family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None
)
print("Socket created.")
hostname = "localhost"
portno = 9999
mySocket.bind((hostname, portno))
print("Socket bound to address {} and port number {}".format(hostname, portno))
mySocket.listen(5)
print("Listening for client.")
while True:
    client, client_addr = mySocket.accept()
    print("Connection established with client at address {}".format(client_addr))
    msg = client.recv(1024).decode()
    print("Message received from the client:")
    print(msg)
    print("Sending acknowledgment to the client.")
    msg_out = "Message received: {}. Thank you.".format(msg).encode()
    client.send(msg_out)
    print("Terminating the connection.")
    client.close()
    break

Now that we have created a server let us create a client process that will communicate to the server.

How to Create a Client in Socket Programming

To create a client, we first need to create a socket with the socket() method as we did while creating the server. Remember that the protocols defined for the client socket should be the same as the server socket. Otherwise, the program will not work as desired.

After creating the socket, we need to connect it to the server. For this, we will use the connect() method.

Connect to the Server: The connect() Method

The syntax for the connect() method is as follows.

connect((host, port))

Here, the parameter host denotes the address of the server. The parameter port denotes the port number the server socket is created. You should give the same values as input to the host and port parameter you provided to the bind() method while creating the server.

Communication With the Server

After connecting to the server, you can communicate with the server using the send() and recv() methods. Finally, it would help close the connection from the client-side using the close() method.

Following is the client program we will use to create a client process.

import socket

mySocket = socket.socket(
    family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None
)
print("Socket created.")
hostname = "localhost"
portno = 9999
mySocket.connect((hostname, portno))
print("Connection established with the server.")
msg = "Hi I am a TCP client created by Aditya."
print("Sending msg to the server:", msg)
mySocket.send(msg.encode())
msg_in = mySocket.recv(1024).decode()
print("Acknowledgment received from the server:")
print(msg_in)
print("Terminating the Connection.")
mySocket.close()

Having created the server and the client, let us now run the programs. Remember that you should run both the client program and the server program simultaneously so that both the processes can be alive simultaneously and communicate with each other.

The output in the terminal with the server program will look like this:

Socket created.
Socket bound to address localhost and port number 9999
Listening for client.
Connection established with client at address ('127.0.0.1', 37958)
Message received from the client:
Hi I am a TCP client created by Aditya.
Sending acknowledgment to the client.
Terminating the connection.

The output in the terminal with the client program will look like this:

Socket created.
Connection established with the server.
Sending msg to the server: Hi I am a TCP client created by Aditya.
Acknowledgment received from the server:
Message received: Hi I am a TCP client created by Aditya.. Thank you.
Terminating the Connection.

Socket Programming With the UDP Protocol in Python

In the previous sections, we have created sockets that follow the TCP protocol in the connection. In TCP protocol, the connection between the client and the server is maintained throughout the communication.

However, there are many situations where we cannot maintain a stable connection between the client and the server due to resource constraints. Therefore we need a communication protocol that doesn’t require a stable connection. For this, we use the UDP protocol.

How to Create a Server With UDP Protocol in Python

To create a connection with the UDP protocol, we need to follow the following steps while implementing the server.

  • Specify SOCK_DGRAM in the input to the type parameter while creating the server socket with the socket() method.
  • Bind the socket to an address and a port number using the bind() method.
  • As we don’t need to establish a connection with the client, we don’t use the listen() and accept() methods to establish the connection. We can directly start communicating with the client.
  • To receive a message in the UDP protocol, we use the recvfrom() method. It takes the number of bytes to read as an input argument and returns a tuple containing the data and the address from which the data has been received.
  • To send a message in the UDP protocol, we use the sendto() method. The sendto() method takes the data as its first input argument and a tuple containing the hostname and port number as the socket’s address to which the data will be sent.
  • After communication, you must close the socket using the close() method.

Using the following Python program, you can implement a server process that communicates with UDP protocol.

import socket

mySocket = socket.socket(
    family=socket.AF_INET, type=socket.SOCK_DGRAM, proto=0, fileno=None
)
print("Socket created.")
hostname = "localhost"
portno = 9999
mySocket.bind((hostname, portno))
print("Socket bound to address {} and port number {}".format(hostname, portno))
while True:
    msg, client_addr = mySocket.recvfrom(1024)
    print("Message received from the client:")
    print(msg.decode())
    print("Sending acknowledgment to the client.")
    msg_out = "Message received: {}. Thank you.".format(msg).encode()
    mySocket.sendto(msg_out, client_addr)
    mySocket.close()
    break

How to Create a Client With UDP Protocol in Python

To create a client process that follows the UDP protocol, we need to create the socket by specifying SOCK_DGRAM in the input to the type parameter while creating the server socket with the socket() method. We don’t need to use the connect() method here as we don’t have to create a connection.

After creating the socket, we can directly start communicating with the server using the sendto() and recvfrom() methods. After communicating with the server, don’t forget to close the socket using the close() method.

Using the following Python program, you can implement a client process that communicates with UDP protocol.

import socket

mySocket = socket.socket(
    family=socket.AF_INET, type=socket.SOCK_DGRAM, proto=0, fileno=None
)
print("Socket created.")
while True:
    msg = "Hi I am a UDP client created by Aditya."
    print("Sending msg to the server:", msg)
    mySocket.sendto(msg.encode(), ("localhost", 9999))
    msg_in = mySocket.recv(1024).decode()
    print("Acknowledgment received from the server:")
    print(msg_in)
    print("Terminating the Connection.")
    mySocket.close()
    break

Again, to observe the output, you should run both the client program and the server program simultaneously so that both the processes can be alive at the same time and can communicate with each other.

The output in the terminal with the server program will look like this:

Socket created.
Socket bound to address localhost and port number 9999
Message received from the client:
Hi I am a UDP client created by Aditya.
Sending acknowledgment to the client.

The output in the terminal with the client program will look like this:

Socket created.
Sending msg to the server: Hi I am a UDP client created by Aditya.
Acknowledgment received from the server:
Message received: b'Hi I am a UDP client created by Aditya.'. Thank you.
Terminating the Connection.

Conclusion

In this article, we have discussed socket programming in Python. We have also implemented client and server programs separately using the TCP and UDP protocols to learn the basics of socket programming in Python.

TCP is connection-oriented and hence a reliable protocol. While using the TCP protocol, it is guaranteed that the messages will reach from the server to the client and vice versa. In UDP, it is not guaranteed that the message will be delivered to the desired destination.

On the other hand, the UDP protocol is faster and easy to implement, while the TCP protocol is slower. Also, the TCP protocol cannot be used for broadcasting, while we can use the UDP protocol for broadcasting.

Depending on the available resources and your need, you can choose any protocol to implement client-server communication using sockets.

Author: Aditya Raj
Aditya Raj avatar Aditya Raj avatar

Aditya Raj is a highly skilled technical professional with a background in IT and business, holding an Integrated B.Tech (IT) and MBA (IT) from the Indian Institute of Information Technology Allahabad. With a solid foundation in data analytics, programming languages (C, Java, Python), and software environments, Aditya has excelled in various roles. He has significant experience as a Technical Content Writer for Python on multiple platforms and has interned in data analytics at Apollo Clinics. His projects demonstrate a keen interest in cutting-edge technology and problem-solving, showcasing his proficiency in areas like data mining and software development. Aditya's achievements include securing a top position in a project demonstration competition and gaining certifications in Python, SQL, and digital marketing fundamentals.

GitHub

Related Article - Python Socket

Related Article - Python Module