Python Socket Programming Tutorial

Python stands out as an exceptionally versatile programming language, boasting an extensive array of libraries applicable across nearly all contemporary domains. Its straightforward syntax and approachable environment facilitate seamless development and data analysis, making it an ideal choice for both novice and experienced developers alike.

Python is well-suited for network programming and includes a variety of libraries that provide advanced access to specific application-layer network protocols, including but not limited to HTTP and FTP. Before delving deeper, it is essential to grasp the fundamental terminology associated with networking.

Recent advancements in socket programming with Python have focused on boosting performance, enhancing security, and improving scalability. The integration of asynchronous frameworks and libraries, including asyncio and aiohttp, has enabled developers to handle network operations concurrently and with greater efficiency.

Asynchronous programming is gaining traction among Python developers as it allows for the creation of non-blocking, concurrent code that efficiently handles multiple connections. The asyncio library in Python serves as a cornerstone for asynchronous programming, facilitating the creation of event loops and coroutines. With asyncio, developers can manage several connections concurrently without the need for additional threads or processes in socket programming, thereby enhancing both performance and resource efficiency.

In addition to enhancements in speed, security has become a crucial aspect of socket programming. Python provides a variety of modules and protocols aimed at ensuring secure network connections, such as TLS (Transport Layer Security) and SSL (Secure Socket Layer). These encryption methods safeguard data transmitted across the network against unauthorized access and tampering. By integrating secure communication protocols into socket programming with Python, developers can better protect sensitive data and maintain the integrity of interconnected systems.

Moreover, scalability has emerged as a crucial element in modern socket programming. Widely utilized Python web development frameworks such as Flask and Django provide integrated capabilities for handling network requests and responses. These frameworks simplify the intricacies of socket programming, enabling developers to focus on building scalable web applications that incorporate functionalities such as load balancing, caching, and distributed computing.

What is Computer Network ?

Computer networks enable the sharing of resources and facilitate communication among multiple computer systems or devices. The framework that links these devices and permits the transfer of information among them is referred to as a computer network. To enable communication and collaboration, it is essential to establish a network connection.

To illustrate the concept of computer networks, let’s consider the process of making a phone call. When we initiate a call, the network service provider is responsible for establishing a connection between our device and the device of the person we are calling. This scenario mirrors the necessities of computer networks, where it is essential for devices to be interconnected to facilitate data exchange and enable access to communal resources.

Computer networks may be divided into several categories based on their size and coverage area. Typical network types include the following:

  • Local Area Network (LAN): A LAN is a network that covers a restricted area of land, such as a campus, office building, or other similar structures. It links devices within a constrained space, enabling quick and effective communication.
  • Wide region Network (WAN): A WAN links several LANs and often spans a greater geographic region. It makes it possible for gadgets to communicate with each other across towns, nations, and even continents. An expansive, worldwide WAN is exemplified by the Internet.
  • Metropolitan Area Network (MAN): Regarding geographic coverage, a MAN sits between a LAN and a WAN. It links devices throughout a city or metropolitan region, enabling more extensive resource sharing and communication.
  • PAN: PAN (Personal Area Network) is a network that connects devices within an individual's personal space, such as a smartphone, smartwatch, and computer.
  • Wireless Networks: Wireless networks build connections without physical wires using wireless communication technologies like Wi-Fi, Bluetooth, or cellular networks. They enable devices to connect and communicate with flexibility and mobility.

To operate efficiently, computer networks need various hardware and software components. These consist of the following:

  • NIC: Network interface cards (NICs) are physical objects used to connect devices to a network. They give network-connected devices a physical interface to send and receive data.
  • Routers and switches: Routers and switches are networking tools that aid in rerouting and directing network traffic. Switches enable communication inside a network by routing data to the correct receiver, whereas routers link several networks and permit data transmission between them.
  • Protocols: The rules and norms for communication between devices on a network are defined by protocols or network standards. Common protocols include HTTP (Hypertext Transfer Protocol), which is used for online communication, and TCP/IP (Transmission Control Protocol/Internet Protocol), the Internet's founding protocol.
  • Network Security: To safeguard sensitive data and prevent unauthorized access, it is essential to ensure the security of computer networks. Virtual private networks (VPNs), firewalls, encryption, and authentication techniques are examples of network security methods.

As technology progresses, computer networks are evolving correspondingly. The advent of innovative technologies such as the Internet of Things (IoT) and 5G is transforming networks by connecting a growing array of devices and facilitating faster, more dependable communication.

A type of computer networking referred to as a local area network (LAN) connects a limited number of computers within a specific geographic area. It is commonly employed in environments such as residences, offices, small enterprises, and educational institutions. Typically, the devices within a LAN are linked in a peer-to-peer configuration, which facilitates direct communication and the sharing of resources among them.

The scale of a Local Area Network (LAN) can range from a minimal setup featuring just one user to a comprehensive corporate network accommodating numerous users and devices. LANs provide an efficient and cost-effective solution to connect devices within a limited area, facilitating seamless communication and collaboration among users.

With the evolution of networking technologies, Local Area Networks (LANs) have undergone significant transformations. In contemporary settings, wireless Local Area Networks (WLANs) are increasingly prevalent due to their ability to offer flexible wireless connectivity within a limited area. WLANs leverage Wi-Fi technology to enable devices to connect to the network without relying on physical cables.

Numerous Local Area Networks (LANs) are interconnected through a Wide Area Network (WAN), which covers an extensive geographical area. The internet serves as a prime example, facilitating communication over vast distances. In WANs, data is divided into smaller packets for separate transmission utilizing packet switching. This method allows for simultaneous data streams and maximizes the efficiency of network resources.

Wide Area Networks (WANs) are vital for organizations with multiple locations, as they enable seamless communication and the transfer of information among branch offices. Additionally, they are instrumental in distributed systems and cloud computing by providing access to remote resources. Performance improvements are achieved through WAN optimization techniques such as data compression. Advances in technology, including fiber optic cables and 5G networks, have significantly boosted WAN bandwidth and speed. Solutions like Software-Defined WAN (SD-WAN) enhance flexibility and streamline management processes. To meet the growing requirements for global connectivity, WANs are continually evolving.

A network referred to as a Metropolitan Area Network (MAN) encompasses a range that is less extensive than that of a Wide Area Network (WAN) but spans a broader geographic area than a Local Area Network (LAN). This type of network links computer users and resources over a significant geographic space, typically within a city or metropolitan region.

A MAN facilitates the interconnection of multiple LANs or various networking technologies within a specified metropolitan region, thereby broadening communication opportunities beyond the limitations of an individual LAN. This framework enables nearby businesses or organizations to collaborate more effectively, share resources, exchange data, and enhance their communication capabilities.

A Metropolitan Area Network (MAN) is a quintessential example of a network infrastructure that connects multiple buildings, universities, or workplaces within an urban environment. By establishing a unified, expansive network, a MAN facilitates efficient resource sharing and communication among the interconnected locations. It is well-suited for applications requiring extensive connectivity across a specific metropolitan or suburban area, as it offers greater bandwidth and broader coverage compared to a Local Area Network (LAN).

Personal digital assistants (PDAs), personal computers (PCs), mobile phones, and tablets can all connect through a personal area network (PAN). The primary purpose of a PAN is to enable data exchange and communication between different personal devices.

Personal Area Networks (PANs) can serve various purposes, such as connecting devices to one another or integrating them into a more extensive network. For example, a PAN can establish a wireless connection between a laptop and a smartphone, allowing for data sharing and Internet access. Furthermore, it can facilitate the connection of devices to a broader network, such as the Internet or a Local Area Network (LAN).

Bluetooth technology is commonly utilized for the creation of Personal Area Networks (PANs). This technology facilitates wireless communication over short distances, typically up to 10 meters. Devices that feature Bluetooth capabilities can connect and establish a pairing with each other, allowing them to form a PAN.

Personal Area Networks (PANs) enable individuals to effortlessly and flexibly connect with and communicate between their personal devices. Operating within a limited range, they facilitate efficient data transfer, file sharing, and synchronization among devices. PANs are especially beneficial in scenarios where multiple personal devices need to interact with each other or connect to a broader network.

Wireless Networks

Wireless networks refer to systems that transmit data and establish connections among devices through wireless communication technologies, eliminating the need for physical cables or wired links. These networks enable devices to connect and share information without wires, offering flexibility, portability, and convenience across a range of applications.

Data exchange among devices occurs via wireless networks utilizing radio frequencies, infrared signals, and various other wireless communication techniques. Wi-Fi stands out as the most widely used type of wireless networking technology. It allows devices to connect to a local wireless network, typically provided by a wireless router, thus enabling them to access the internet or interact with other devices within the network. Today, Wi-Fi networks can be found in residential spaces, commercial establishments, public venues, and several other environments, delivering wireless connectivity for an array of devices, including smartphones, laptops, tablets, and Internet of Things (IoT) devices.

Bluetooth represents a prominent wireless technology that is specifically designed for short-range communication among devices. This technology enables wireless connectivity between devices that are in close proximity, allowing users to link their smartphones to wireless headphones or transfer files between these devices effortlessly.

An additional type of wireless network that provides internet connectivity and mobile communication to devices over an expansive geographical area is the cellular network, encompassing 3G, 4G, and 5G technologies. Cellular networks rely on a system of base stations or cell towers to relay signals between devices and the overarching network infrastructure. This setup allows users to engage in phone conversations, send SMS messages, and access online services while on the move.

Computer Network Terminologies

These terms are critical for network programming. If you are not acquainted with them, it is important to familiarize yourself with these concepts before proceeding to the next tutorial.

Internet Protocol

The process of transmitting and receiving data across the Internet is regulated by a framework of guidelines and procedures referred to as Internet Protocol (IP). This protocol serves as a fundamental element of the Internet protocol suite and acts as the foundation for digital communication.

IP allocates a distinct IP address to each device connected to a network, facilitating a method for unique identification. IP addresses serve as numerical identifiers that allow for the recognition and localization of devices within a network environment. The two active versions of IP are IPv4 (Internet Protocol version 4) and IPv6 (Internet Protocol version 6). Unlike IPv4 addresses, which consist of four numerical segments divided by periods, IPv6 addresses are formatted as eight groups of four hexadecimal digits, separated by colons.

For instance, consider two friends, A and B. If A wishes to send a message to B, he writes a letter and heads to the Post Office (which serves as a type of communication network). A then places the letter inside an envelope and submits it at the Post Office for delivery to B. He includes B's address to ensure that the letter arrives at the intended location.

At this point, A intends to forward a 15-page script to B. However, it’s possible that a single envelope may not accommodate all the pages. Consequently, A opts to place each individual page into its own separate envelope. This raises the possibility that the postal service may not deliver the envelopes in the sequence they were originally intended. In this scenario, the role of the internet protocol becomes crucial.

The routing of data packets within networks is managed by the Internet Protocol (IP). When transmitting data over the internet, it is divided into smaller packets that contain critical addressing details along with a segment of the original message. These packets are dispatched independently, and the routes they take may differ. IP employs IP addresses to direct packets through networks and takes care of packet fragmentation and reassembly to ensure that every packet reaches its intended destination.

  • UDP(User Datagram Protocol)
  • TCP(Transmission Control Protocol)

User Datagram Protocol

UDP is characterized by its unordered nature. Recipients may receive datagrams out of the order in which they were sent. Each datagram is treated independently by UDP, without enforcing any specific sequence or arrangement. This property can be advantageous in scenarios where the prompt transmission of data takes precedence over the precise order of delivery.

Due to the fact that a connection does not have to be set up prior to data transmission, UDP is characterized as a lightweight protocol. Unlike TCP, which necessitates a handshake procedure to create a reliable connection, UDP operates on a best-effort principle without the overhead of connection management. This lightweight characteristic of UDP enhances its efficiency in terms of resource utilization and processing demands. The routing of data packets across networks is conducted by IP. When data is transmitted over the internet, it is divided into smaller packets, each containing necessary addressing details alongside a segment of the original message. These packets are dispatched individually, and their routes may differ during transit. IP employs IP addresses to direct packets through networks and manages the fragmentation and reassembly of packets to ensure that each one reaches its intended destination correctly.

The data units utilized by UDP are referred to as datagrams. Each datagram manages the necessary information for both transmission and integrity validation as an independent entity. These datagrams are sent individually and may take various paths to reach their endpoint. UDP lacks mechanisms for retransmission or error correction. Consequently, it is the responsibility of the application layer to guarantee the integrity and reliability of the data as required.

Transmission Control Protocol

TCP, known as the Transmission Control Protocol, is a connection-oriented protocol designed to ensure reliable and orderly data transmission over the Internet. It operates by first establishing a connection with a remote host prior to initiating any data transfer, utilizing the concept of a handshake to accomplish this.

When one host transmits "Hello," and the other replies with "Hello," the connection is successfully initiated. This process is known as the handshake procedure in TCP. It is essential for both hosts to finalize this handshake in order to facilitate data sharing over the network.

TCP possesses several properties that differentiate it from UDP:

  • Reliability: Because TCP has procedures for message acknowledgment, retransmission of missing packets, and timeout management, it is more dependable than UDP. It ensures the data is transmitted successfully and allows for repeated transmission attempts if necessary.
  • Ordered: TCP ensures that messages are transmitted in the correct sequence. The messages are sent to the recipient in the same sequence that they were sent. This guarantees accurate data reconstruction at the receiving end.
  • Heavyweight: When compared to UDP, TCP is somewhat heavyweight. Before any user data is transmitted, a socket connection must be established by a three-packet procedure known as a three-way handshake. SYN (synchronization), SYN+ACK (acknowledgment), and ACK (acknowledgment) are the three packets in question. This handshake process adds some overhead to the communication but ensures a reliable connection.

TCP is commonly utilized for applications such as web browsing, file transfers, and email, all of which require reliable and orderly data transmission. It ensures data integrity and completeness by employing techniques such as error detection, flow management, and congestion handling.

IP Addresses and Ports

A network, which encompasses the internet, allocates IP addresses to devices that are connected, providing them with unique numerical identifiers. These addresses serve as both location and identification data for various devices, including computers, servers, and Internet of Things (IoT) devices. IP addresses are essential for establishing connections between devices on the internet.

Conversely, ports serve as endpoints within an operating system, facilitating communication among different applications or services. Each port is assigned a numerical identifier that distinguishes between various services or processes running on a device. By utilizing ports, a device allows multiple applications to operate concurrently and simplifies the transfer of data between these applications.

Example -

In the earlier illustration, A intends to send a letter to B. Therefore, A needs to obtain B's address to ensure the successful delivery of the package. Now that A possesses B's specific postal address, the postman is able to deliver the letter without any issues. Similarly, an IP address functions like a postal address.

A system may operate thousands of services simultaneously; however, each service can be distinctly recognized by its port number. The available range of ports on a system spans from 0 to 65535.

An IP address can be likened to the physical address of a building, while a port can be seen as the specific room number located within that building. The device is recognized by its IP address, whereas the port serves to indicate the particular program or service that is running on that device.

IP addresses and ports function in tandem to facilitate accurate communication among devices and applications within a network. When data is transmitted over the internet, it is directed to a specific IP address and dispatched to a designated port on the intended device, which is linked to a particular application or service. Subsequently, the application or service in question can properly receive and process the incoming data.

Occasionally, the port number may be visible in web addresses or other uniform resource locators (URLs) as well. By default, HTTP operates on port 80, while HTTPS utilizes port 443. Presented below are examples of commonly used ports.

Port Number Description
22 Secure Shell
23 Telnet Remote Login Service
25 Simple Mail Transfer Protocol (SMTP)
53 Domain Name System (DNS) Service
80 Hyper Text Transfer Protocol (HTTP) which used in WWW.

There are two types of the IP addresses.

Private IP Address: Local networks, such as those in a house or business, employ private IP addresses inaccessible from the internet. Three private IP address ranges are frequently employed:

  • 168.0.0 - 192.168.255.255
  • 16.0.0 - 172.31.255.255
  • 0.0.0 - 10.255.255.255

Due to the utilization of these private IP addresses, devices on a local network can communicate with each other without the need for direct internet access. These addresses are commonly employed in local area networks (LANs), residential networks, and small business environments.

Public IP Address: Conversely, an internet service provider (ISP) assigns a public IP address to a router or gateway device that is connected to the internet. This address is unique and can be routed globally, facilitating communication with external networks for devices connected to the internet. Public IP addresses are essential for devices to be accessible over the internet and to interact with websites and various online services.

Internet Service Providers (ISPs) provide public IP addresses that can either be dynamic, meaning they can change over time, or static, which remain constant. Static public IP addresses are commonly utilized for applications that require consistent accessibility, including web servers or remote access to networks. On the other hand, dynamic public IP addresses are subject to frequent changes.

Firewall

A firewall serves as a protective barrier separating an internal network from external entities, including the Internet, and plays a crucial role in safeguarding network security. Its primary functions consist of overseeing both incoming and outgoing network traffic while implementing a specified array of security protocols. The firewall inspects data packets and determines whether to permit or block the traffic based on the established rules.

The primary function of a firewall is to protect against threats originating from within a network, including harmful attacks, unauthorized entry, and potential data leaks. It executes its filtering capability by examining the source and destination addresses of each data packet, along with port numbers and other relevant information. Only those packets that meet the established security criteria are permitted to pass through, while any packets deemed suspicious or potentially harmful are denied access.

For example

Consider IP addresses as residences and port numbers as individual rooms within those residences. Only individuals who have been authenticated (source address) are permitted entry into the residence (destination address).

Why Python for Networking Programming?

Python, renowned for its flexibility and strength as a programming language, has gained immense popularity in the realm of network programming. Several reasons contribute to Python being a preferred choice for this domain, and in this discussion, we will delve into some of the primary factors.

To begin with, Python stands out as a superb choice for network programming owing to its clarity and ease of use. Its intuitive and consistent syntax enables developers to write code that is both easy to follow and maintain. Thanks to this user-friendliness, Python code tends to exhibit fewer bugs, as it is less prone to mistakes. Moreover, Python's vast standard library provides a rich array of modules and functions specifically tailored for networking, facilitating the seamless implementation of network protocols and communication.

Furthermore, Python's cross-platform compatibility makes it an exceptional choice for network programming. Python applications can operate seamlessly on Windows, macOS, and Linux systems without necessitating extensive alterations. This adaptability is crucial in network programming, as networks often comprise diverse devices and systems. The portability of Python facilitates the installation and execution of network applications across multiple platforms, thereby simplifying the process of developing and maintaining these applications.

Python boasts a vast ecosystem and a robust community support system, which is another major benefit. Numerous third-party libraries and frameworks exist for Python that can significantly facilitate network programming activities. Libraries such as "socket" and "asyncio" offer high-level abstractions for network communication, simplifying socket management and the implementation of networking protocols. Frameworks like 'Curved' and 'Django' provide a comprehensive set of tools and components for constructing sophisticated network applications, including web servers and APIs. The availability of these resources allows developers to leverage existing solutions, thereby speeding up development processes and minimizing overall workload.

Moreover, the versatility of Python allows it to effortlessly connect with a multitude of technologies and programming languages. It facilitates the interaction of network applications with components developed in diverse languages, owing to its support for various inter-language communication techniques such as APIs, sockets, and message queues. This feature proves particularly beneficial when dealing with existing network infrastructures or tools that are implemented in languages other than Python. Python's proficiency in collaborating with different technologies enhances the ease of integration and fosters smooth cooperation, ultimately improving the overall efficiency of network programming endeavors.

Finally, the widespread appeal of Python in the realm of network programming is significantly enhanced by its comprehensive documentation and a vast community. The dynamic and engaged Python community provides a multitude of online resources, tutorials, and forums where developers can seek assistance and exchange insights. With such detailed documentation, developers can readily obtain information and resolve common networking challenges.

Basic of Socket Programming

We have explored the fundamental principles of networking and have familiarized ourselves with essential networking terminology. Prior to diving into Python network programming, it is important that we first examine an introduction to sockets.

Networking and sockets programming encompass vast areas of study. While computer networking includes numerous topics to delve into, this discussion will focus on the foundational aspects of network programming utilizing Python.

Let’s explore the concept of sockets, examining their definition and the reasons for their utilization.

What is Socket?

Initially, it is essential to understand the concept of an internet connection. An internet connection fundamentally serves to link two endpoints over the internet, enabling the exchange of data and facilitating various other activities.

A socket serves as a software interface that allows for communication between two computers over a network, like the Internet. It acts as an endpoint for sending and receiving data between applications running on different devices. This internet connectivity allows a process on computer C1 to interact with a process on computer C2. The socket encompasses the following characteristics:

Reliable: Sockets offer a trustworthy means of transmitting data over an internet connection. They ensure precise and error-free transmission of information while creating a secure communication channel between the client and the server.

Point to Point: Sockets establish a connection between two specific endpoints in a direct point-to-point manner. This setup allows for the transmission and reception of data at the intended destination, as each endpoint can be identified by its IP address and port number.

Full Duplex: One of the essential features of sockets is their capability for full-duplex communication. This means that data can be transmitted simultaneously in both directions between the client and the server. Both the client and the server are able to send and receive data, facilitating interactive and bidirectional exchanges.

Sockets serve as the endpoints for bidirectional, point-to-point communication channels, playing a crucial role in network connectivity. They are commonly utilized for transmitting messages across networks. When a client, such as a web browser, establishes a connection with a server, like www.logic-practice.com, two endpoints come into play: the client socket and the server socket.

The concept of sockets was initially introduced in 1971 and subsequently evolved into the Berkeley socket Application Programming Interface (API), which was incorporated into the Berkeley Software Distribution (BSD) operating system in 1983.

Client-server applications gained widespread adoption in the 1990s following the introduction of the Internet and the World Wide Web, which significantly increased the use of sockets. In this model, one entity operates as the server, standing by to receive connections from clients. This methodology enables a variety of networked services, such as web servers, email servers, and database servers, while efficiently handling multiple clients simultaneously.

Sockets facilitate interaction between clients and servers through various protocols, notably the User Datagram Protocol (UDP) and the Transmission Control Protocol (TCP). The reliable, connection-oriented TCP protocol ensures that data packets are transmitted in the correct sequence. It establishes a connection between the client and server, ensuring the precision and reliability of data transmission. In contrast, UDP is a streamlined, connectionless protocol that prioritizes speed over reliability. This low-latency approach makes it particularly suitable for real-time applications, where rapid communication is essential.

There is no specific programming language mandated for socket programming. It is compatible with a variety of languages, such as Python, Java, C++, and C#, allowing developers to utilize it across different platforms.

In order to facilitate the adoption of emerging technologies, socket programming has evolved significantly in recent years. For example, the implementation of IPv6 has enhanced both connectivity and addressing schemes to cater to the growing multitude of devices linked to the Internet.

Socket API Functions

Application programmers may construct, configure, and manage sockets in their network applications using the Socket API (Application Programming Interface), which offers a collection of functions. These activities include creating sockets, binding to particular addresses, creating connections, exchanging data, and shutting sockets, among others. Following are a few frequently used Socket API functions:

  • socket: A new socket is created using the socket method, providing a socket descriptor that may be utilized for later actions. It accepts arguments that indicate the socket type (such as SOCKSTREAM for TCP or SOCKDGRAM for UDP) and the address family (such as AFINET for IPv4 or AFINET6 for IPv6).
  • bind: Using the bind method, a socket may be bound to a particular IP address or port on the network. The IP on which the server will listen for inbound connections is commonly specified on the server side.
  • listen: A socket can accept incoming connections by being marked as a passive socket using the method listen. The socket's maximum capacity for pending connections is specified.
  • accept: Using the accept method, a listening socket can accept incoming connection requests. For the accepted connection, it generates a fresh socket and returns a new socket descriptor. On the server side, this function is commonly employed.
  • connect: This method starts a client socket connection to a distant server. It creates a connection using the address of the distant server.
  • send and recv: These two functions-send and recv-are used to send and receive data across a socket. They give the client and server the means to send and receive messages. These operations provide timely and trustworthy data transmission for connection-oriented sockets like TCP.
  • sendto and recvfrom: In contrast to send and recv, sendto and recvfrom are used with connectionless sockets, such as UDP. They enable data transmitting and receiving without first establishing a connection.
  • close: Using the close method, a socket is closed, and all related resources are released. For connected sockets, it breaks the connection and stops any further communication.
  • getaddrinfo: Based on a hostname, port, and other factors, this function is used to compile a list of appropriate network addresses. It offers both IPv4 and IPv6 network address resolution flexibility.
  • setsockopt: This method enables socket option modification. It allows for precise management of several socket properties, including setting the socket to reuse addresses, changing socket buffer sizes, and activating multicast options.
  • getsockopt: Gets the current value of a socket option using the getsockopt method. It enables requesting information about the current configurations or states of socket options, such as finding out the timeout value or the value of a certain socket flag.
  • shutdown: With the help of the shutdown method, a socket connection may be gracefully terminated. It can terminate a connection's transmitting or receiving end or both. Before shutting the socket, it checks that all outstanding data has been transferred.
  • select: This function enables waiting until at least one socket is prepared for reading, writing, or unusual circumstances before monitoring several sockets for activity. It helps manage numerous sockets effectively and simultaneously.
  • gethostbyname and gethostbyaddr: DNS (Domain Name System) resolution uses these functions. They either convert IP addresses to hostnames (gethostbyname) or hostnames to IP addresses (gethostbyaddr).
  • inetntop and inetpton : These two functions, inetntop and inetpton, make it easier to translate human-readable IP addresses from string format to binary form. When using IP addresses in network programming, they are useful.
  • fcntl: This function offers a variety of operations for working with file descriptors, such as setting their flags or switching their non-blocking mode.
  • Creating a Socket

Upon clicking the link that directed us to a specific page, the web browser behaves in the following manners:

Client.py

Example

import socket
# we create a socket object to establish the connection.
Client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# now connect to the web server on port 80
# - the normal http port
Client_socket.connect(("www.logic-practice.com", 80))

The code provided will function on the client side. When the client attempts to establish communication with the server, the operating system allocates an Ephemeral Port for that connection. An Ephemeral Port refers to a temporary port number that is randomly assigned by the operating system. Once the data transfer has concluded, the client socket is closed immediately. This client socket is utilized solely for that single instance of communication.

The server establishes a server socket, which is somewhat more intricate than a client socket. Let's explore the processes that occur on the server side.

Server.py

Example

import socket
Server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#We bind the socket to a public host and a well-known port
Server_socket.bind((socket.gethostname(), 80))

#It become a server socket and listen for connections
Server_socket.listen(5)

Difference between Client and Server Socket:

Client Socket

  • To connect to a server, client programs employ client sockets.
  • They start a conversation by making queries to the server. Then they get replies.
  • Client connections are temporary and made for certain interactions or activities.
  • Ephemeral ports, which the operating system dynamically assigns, are often used by them for communication.
  • Data sent to the server and received must be processed by client sockets.
  • Server Socket:

  • Applications running on servers employ server sockets to check for new client connections.
  • They wait for connections from clients and manage several client connections simultaneously.
  • Server sockets have a long lifespan and are intended to be always available.
  • They operate by listening on specified ports linked to particular services or protocols.
  • Server sockets are in charge of receiving incoming client connections and responding with services or data.
  • They can frequently manage several client connections at once by setting up different threads or processes for every connection.
  • Python Socket Module:

The socket module in Python offers the necessary functions for creating and utilizing sockets. The main method for socket creation is Socket.socket. The syntax for the socket function is outlined below:

Example

Create_Socket = socket.socket(socket_family, socket_type, protocol=0)

The socket method's arguments are as follows:

  • socketfamily: The address family for the socket is specified by socketfamily. It can be either AFUNIX (for sockets in the Unix domain) or AFINET (in the Internet domain).
  • sockettype: the socket's type is specified by sockettype. For TCP sockets, it can be SOCKSTREAM, and for UDP sockets, it can be SOCKDGRAM.
  • protocol: specifies the particular protocol to be used. It is normally set to 0, enabling the operating system to select the proper protocol following the provided socket_type.

Typically, we will utilize AFINET sockets, which are designated for the Internet domain, along with SOCKSTREAM sockets that are intended for TCP connections. After establishing the socket, we can employ a range of functions available in the socket module to engage with the socket, including bind, connect, listen, send, recv, among others.

These techniques enable us to associate the socket with a designated address and port, create a connection to a distant server, monitor for incoming connections, transmit data, receive data, and carry out various operations related to sockets.

In the client-server socket architecture, the client socket establishes a connection to the server, whereas the server socket remains in a state of readiness to accept incoming connections. The client socket employs the connect function to initiate this connection, while the server socket prepares itself by utilizing the bind and listen functions.

When developing network applications that employ socket communication, it is crucial to understand and effectively utilize the functions provided by the Python socket module.

Client Sockets Methods

The client socket method is given below.

connect

This function establishes a connection to a remote socket specified by an address. The address format consists of a combination of the host and port pair, which is applicable for the AF_INET address family.

Server Socket Methods

The server socket methods are given below.

bind

This technique is employed to associate the socket with a specific address. The format of the address is contingent upon the socket family referenced earlier (AF_INET).

listen(backlog)

This approach is utilized to monitor the connections established with the socket. The term backlog refers to the highest number of pending connections that can be queued for listening before any new connections are declined.

accepts

The accepts function is responsible for accepting an incoming connection. Prior to calling this method, the socket must be associated with an address and be prepared to listen for incoming connections. It returns a tuple (conn, address), where conn represents a new socket object that can be utilized for sending and receiving data over the established connection, and address indicates the address associated with the socket at the other end of the connection.

Few Common Socket Methods

Below are several frequently utilized functions for the server object.

Example

Server_Object = socket.socket(socket_family, socket_type, protocol = 0)
TCP Socket Methods UDP Socket Methods
Server_Object.recv()- Receives TCP messages Server_Object.recvfrom()- Receive UDP messages.
Server_Object.send() - Transmit TCP messages Server_Object.sendto()- Transmits UDP messages.

Types of Sockets

In the realm of networking, you will encounter two primary types of sockets: SOCKSTREAM and SOCKDGRAM. Let’s delve deeper into each type:

SOCK_STREAM:

  • TCP (Transmission Control Protocol)-based communication uses SOCK_STREAM sockets.
  • They offer a dependable stream of data that is connection-focused.
  • Data is transferred via SOCK_STREAM in a continuous stream, guaranteeing that it will arrive in the same order as it was sent.
  • These sockets ensure data delivery and automatically manage any retransmissions or missed packets.
  • Applications that demand dependable and organized data delivery, such as web surfing, file transfers, email, and real-time communication protocols like HTTP, FTP, and SSH, frequently employ SOCK_STREAM sockets.
  • Data may be delivered and received in both directions since the communication is bidirectional.
  • SOCK_DGRAM:

  • For UDP (User Datagram Protocol)-based communication, SOCK_DGRAM sockets are utilized.
  • They provide an unstable, connectionless datagram service.
  • Data is transmitted via SOCK_DGRAM in separate packets known as datagrams, each of which is a distinct communication unit.
  • Datagrams may be lost or duplicated during transmission, and there is no assurance that they will be received in the order they were sent.
  • Applications like real-time multimedia streaming, online gaming, DNS, and SNMP that can tolerate the odd packet loss or out-of-order delivery frequently employ SOCK_DGRAM sockets.
  • Data may only be sent in one direction during unidirectional communication.
  • TCP Sockets

In this section, we will instantiate the socket object by utilizing the socket.socket function and designate the socket type as socket.SOCK_STREAM. It is well understood that a protocol is crucial for transmitting data from one endpoint to another. In this case, the default protocol employed is TCP (Transmission Control Protocol). This protocol is noted for its efficiency and dependability. The reasons for opting for this protocol include:

  • It is dependable - Should any packet be lost during the transmission to the destination, the sender will retransmit it.
  • Ordered data delivery - Messages are transmitted in the exact sequence they were composed by the sender.

Conversely, User Datagram Protocol (UDP) sockets established using socket.SOCK_DGRAM are characterized by their unreliability. The data received by the recipient may not necessarily arrive in the same sequence as it was transmitted by the sender.

Let us delve into the subsequent illustration of a basic Client-Server application.

Simple Server Program

Example -

Example

#!/usr/bin/python

#This is tcp_server.py script

# Import socket module
import socket

# create a socket object
s = socket.socket()
# Get current machine name
host = socket.gethostname()
# Get port number for connection
port = 9999
# bind with the address
s.bind((host,port))
# listen for connections
print("Waiting for connection...")
s.listen(5)
# connect and accept from client
while True:
   conn,addr = s.accept()
   print('Got Connection from', addr)
   conn.send('Responce From the Server')
   # Close the connection
   conn.close()

The code provided above is currently inactive; it is designed to await a connection from a client on the defined port. If the program executes without any errors, it will produce the subsequent output.

In a similar fashion, each website we access is comprised of a server that hosts its content.

At this stage, we are going to develop a client.py script that will establish a connection with the server.py file.

Simple Client Program

Examine the subsequent client.py script. This client attempts to establish a connection with the server at a specific port; we are designating port 9999, which is a clearly defined port.

Example -

Example

#!/usr/bin/python

#This is tcp_client.py script

import socket
#Create a socket
s = socket.socket()
# Get current machine name
host = socket.gethostname()
 # Client wants to connect to server's
# port number 9999
port = 9999
# 1024 is buffer size or max amount
# of data to be received at once
s.connect((host,port))
print(s.recv(1024))

To obtain the desired outcome, start by executing the server.py script, followed by the execution of the client.py script. If everything functions correctly without any errors, you will see the subsequent output.

Note - Here, the client and server files are running on the same machine, but in the real life server is situated on the different place. The point is to be notice here the client.py is terminated but the server.py is still running. This is also happen in real life scenario.

For instance, when a request is sent to logic-practice.com, the server processes that request and operates continuously (24/7) in the background.

Python Internet Module

Below is a compilation of Python modules that pertain to network programming.

Protocol Common function Port No Python module
HTTP Web pages 80 httplib, urllib, xmlrpclib
NNTP Usenet news 119 nntplib
FTP File transfers 20 ftplib, urllib
SMTP Sending email 25 smtplib
POP3 Fetching email 110 poplib
IMAP4 Fetching email 143 imaplib
Telnet Command lines 23 telnetlib
Gopher Document transfers 70 gopherlib, urllib

The table lists common network protocols, their associated functions, default port numbers, and the corresponding Python modules that can be used for network programming. Let's explain each entry:

  1. HTTP (Hypertext Transfer Protocol):

Utilized for fetching and sending web pages along with associated files.

Default port number: 80.

Python libraries: httplib, urllib, xmlrpclib.

  1. NNTP (Network News Transfer Protocol):

Utilized for retrieving and submitting articles to Usenet news groups.

Default port number: 119.

Python library: nntplib.

  1. FTP (File Transfer Protocol):

Employed for the exchange of files between hosts within a network.

Standard port numbers: 20 (for data transfer) and 21 (for control commands).

Python libraries: ftplib, urllib.

  1. SMTP (Simple Mail Transfer Protocol):

Used for sending email messages between servers.

Default port number: 25.

Python library: smtplib.

  1. POP3 (Post Office Protocol version 3):

Used for retrieving email from a remote server.

Default port number: 110.

Python library: poplib.

  1. IMAP4 (Internet Message Access Protocol version 4):

Employed for the purpose of accessing email from a distant server, offering more sophisticated functionalities compared to POP3.

Default port number: 143.

Python module: imaplib.

  1. Telnet:

Utilized for creating remote command line connections.

Default port number: 23.

Python module: telnetlib.

  1. Gopher:

Utilized for obtaining documents from distant servers.

Default port number: 70.

Python modules: gopherlib, urllib.

These Python libraries provide useful classes and functions for engaging with the associated network protocols. They empower developers to execute various network operations using Python, such as making HTTP requests, fetching emails, transferring files, and much more.

Working with UDP Sockets

We have discovered that when the socket family and socket type are not specified, the default protocol used is TCP. In order to establish a UDP socket, it is essential to explicitly define both the socket family and socket type. Let’s examine the syntax below for clarification.

Syntax -

Example

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

Let’s delve into the details of the UDP server program presented below.

UDP Server Program

Create the following script and save the file as server.py

Example -

Example

import socket

# It is used for UDP protocol
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# Host IP
udp_host = socket.gethostname()
# We are specifying port to connect
udp_port = 12345

#print type(udp_sock)  'type' can be used to see type
            # of any variable ('sock' here)

udp_socket.bind((udp_host,udp_port))

while True:
   print("Waiting for client...")
   data,addr = sock.recvfrom(1024)            #receive data from client
   print("Received Messages:",data," from",addr)

Output:

Output

Waiting for client

UDP Client Program

Save this file named udpclient.py

Example -

Example

import socket
# For creating the udp socket
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# Host IP
udp_host = socket.gethostname()
# We are specifying port to connect
udp_port = 12345

msg = "Welcome to our tutorial"
print("UDP target IP:", udp_host)
print("UDP target Port:", udp_port)
# Sending message to UDP server
udp_socket.sendto(msg,(udp_host,udp_port))

Output:

Output

Waiting for client....
Received Messages: Welcome To Example from('192.168.43.217,5342')
Waiting for client

We have explored the concept of sockets and outlined the process of establishing a connection between client and server sockets.

Echo Client and Server

A client is able to send a message or request to a server through the use of an echo server, which is a simple network application. In response, the server will return the exact same message or request back to the client. This illustrates a basic model of client-server communication.

The echo server works in the following ways:

  • The server monitors a certain network port for incoming client connections.
  • A socket is formed for communication between the client and the server when a client connects to the server.
  • The client communicates with or requests something from the server through the socket.
  • The message is delivered from the client to the server.
  • The server processes the message received (which, in the case of an echo server, may not entail any processing at all).
  • Through the socket, the server communicates the same message or response to the client.
  • The client receives the server's echoed message or answer.
  • The client then can send more messages or cut off communication with the server.

The echo server is commonly utilized for testing and debugging purposes, as it allows the client to verify that the server is effectively receiving and processing messages.

The socket module in Python can be utilized to implement both an echo server and an echo client. Upon receiving a message, the server script listens for incoming connections and sends back the received message to the client. Once a connection is successfully established with the server, the client transmits a message, which is then displayed as the echoed response by the client script.

Working with Input and Output Devices

To facilitate the data exchange between an echo server and its client, input and output streams are essential for establishing communication. These streams are crucial for enabling interaction between the server and the client, allowing the client to obtain an echoed version of the message sent by the server.

The input stream signifies the pathway of data from the client to the server. The server utilizes this stream to obtain the message transmitted by the client. Following the retrieval of data from the input stream, the server proceeds to process the information.

The output stream illustrates the transmission of data from the server to the client. Upon receiving a message from the client, the server disseminates the identical message or a response to the output stream. Subsequently, the client is able to access the reflected message or response from the output stream.

These input and output streams facilitate bidirectional communication between the client and the server, enabling the exchange of data. The server has the capability to receive multiple messages from clients, and it can respond by echoing each message back individually.

Let's understand the following example:

Echo Server

Example

import socket
# Standard loopback interface address (localhost)
host_name = '127.0.0.1'
# Specified Port to listen on (non-privileged ports are > 1023)
port_name = 65432
# TCP Sockets
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((host_name, port_name))
    s.listen()
    conn, addr = s.accept()
    with conn:
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data:
                break
            conn.sendall(data)

Explanation -

The socket.socket method generates a socket object that is compatible with the context manager protocol. This allows us to utilize it within a with statement, eliminating the necessity to explicitly invoke the close method.

We have referred to the address family and socket type, specifically AFINET, which is designated for Internet addressing in the IPv4 format. The socket type SOCKSTREAM corresponds to the TCP protocol, facilitating the transportation of our messages across the network.

The bind function has been utilized to establish a connection between the socket and the specified network interface along with the designated port number.

Example

s.bind((host_name, port_name))

In this context, the host_name denotes the hostname, an IP address, or a blank string. The host is required to be a string formatted as an IPv4 address.

The port number is an integer that ranges from 1 to 65535 (with 0 being reserved). This number specifies the TCP port intended for accepting connections from clients. On certain systems, superuser authentication may be necessary if the port number is less than 1024.

Next, we have implemented the listen function, which allows a server to accept incoming connections.

Example

s.listen()
conn, addr = s.accept()

The listen function, by default, includes a backlog parameter. This backlog parameter indicates the maximum number of connections that the system will reject before it starts refusing any new incoming connections.

The backlog serves to regulate the maximum capacity of the queue designated for awaiting connections.

When a client initiates a connection, the accept function generates and returns a new socket object.

At this point, we have obtained a socket object through the accept function. It is crucial to remember that the socket utilized for communication needs to be separate from the listening socket that the server employs to accept incoming connections.

Example

with conn:
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data:
                break
            conn.sendall(data)

After we finalize the procedure to obtain the connection object from the accept function, we implement an infinite while loop that continually makes blocking calls to conn.recv. The client transmits data, which is then echoed back using conn.sendall.

Echo Client

We will outline the echo client application and save it as echo-client.py:

Program -

Example

import socket
# This represent the server's hostname or IP address
HOST = '127.0.0.1'
# This is port number used by the server
PORT = 65432

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.sendall(b'Hello, world')
    data = s.recv(1024)

print('Received', repr(data))

Explanation:

The echo client is considerably simpler than the echo server. It establishes a connection by creating a socket object, connects to the designated server, and utilizes the s.sendall method to transmit messages. Subsequently, it employs s.recv to receive the server's response, which can then be printed out.

Blocking and Non-Blocking Sockets

In the earlier sections, we explored how the client initiates a request to the server, which then processes that request and returns a response utilizing sockets (TCP/UDP).

Blocking Socket I/O

TCP sockets are typically set up to operate in blocking mode by default. When in blocking mode, the execution of the program is paused until a specific operation is completed. For example, when invoking the connect function to establish a connection to a server, the program will halt and await the successful completion of the connection process.

In certain scenarios, particularly when it is crucial to confirm that one operation has completed before proceeding to the subsequent one, blocking I/O can be advantageous. However, if the operation requires more time than expected, it may introduce delays in the overall execution of the program.

Under certain conditions, it may be necessary to implement a system that can manage or interrupt ongoing connections while they are actively utilized. In such scenarios, adopting a non-blocking mode proves advantageous. By configuring a socket to operate in non-blocking mode, we can enable the program to proceed with its execution while it awaits the completion of particular tasks. This approach grants greater flexibility and control over socket operations.

Non - Blocking Socket I/O

To switch a socket between blocking and non-blocking modes in Python, utilize the setblocking method. By changing a socket to non-blocking mode, we can incorporate additional logic to manage interruptions or perform other tasks while awaiting the completion of socket operations.

The non-blocking mode necessitates thorough error verification and the handling of exceptions associated with non-blocking I/O tasks. Therefore, it is crucial to highlight that it demands careful handling.

Let us explore the subsequent illustration of a Blocking Socket.

Save file blockclient.py

Program

Example

import socket
# Creating a socket object
socket_obj = socket.socket()

host = socket_obj.gethostname()
socket_obj.connect((host, 12345))
socket_obj.setblocking(1)

# Or simply omit this line as by default TCP sockets
# are in blocking mode
# Huge amount of data to be sent
data = "Hello Python\n" *10*1024*1024
# Send data till true
assert socket_obj.send(data)

Now, understand the following blockserver.py:

Program

Example

import socket
# Creating a socket object
socket_obj = socket.socket()

# Defining host name
host = socket.gethostname()
# defining port number
port = 12345

socket_obj.bind((host, port))
socket_obj.listen(5)

while True:
    # accept the connection
    conn, addr = socket_obj.accept()

    data = conn.recv(1024)
    # till data is coming
    while data:
        print(data)
        data = conn.recv(1024)
        # It will execute when all data is received
    print("All Data Received")
    conn.close()
    break

Initially, execute the blockServer.py script followed by the blockClient.py script. The server will persistently output the message "Hello World." This process will continue until all the data transmission is completed. In the previously mentioned script, the client will not display "Hello World" for an extended period. This delay occurs because the client is required to transmit a substantial quantity of strings. This situation will persist until the socket's input/output operations become blocked.

The send function is utilized to transfer data across the server, ensuring that the write buffer is fully populated. The kernel will suspend the process in a sleep state until the data in the buffer has been successfully delivered to the client and the buffer is cleared. After the buffer has been emptied, the kernel will resume the process to retrieve the subsequent segment of data that needs to be transmitted.

Now consider a Non - Blocking Socket.

Program

Example

# non_blocking_client.py

import socket

socket_object = socket.socket()

host = socket.gethostname()
socket_object.connect((host, 12345))
# Now setting to non-blocking mode

socket_object.setblocking(0)
# Huge amount of data to be sent
data = "Hello Python\n" * 10 * 1024 * 1024
# Send data till true
assert socket_object.send(data)

Upon executing the nonblockclient.py script, the program will operate for a brief duration, subsequently displaying the message "All Data Received" before concluding swiftly.

When we configure the socket to be non-blocking using the setblocking(0) method, it will not pause to wait for the operation to finish. Consequently, when we invoke the send function, it will attempt to place the largest possible volume of data into the buffer.

Closing a Connection

Employing the close function on a socket is generally recommended when ending a connection. In most cases, invoking close is adequate, and there is no need for an explicit invocation of the shutdown function prior to closing.

In certain circumstances—especially during an HTTP-like communication—the shutdown method can be advantageous. For example, if the client invokes shutdown(1), it indicates that it has finished sending data. The server can detect the "EOF" (end of file) condition when it receives 0 bytes, which indicates that the client has completed its request. Following this, the server may respond if necessary. The client's ongoing capability to receive data is confirmed when the transmission operation is successful.

In the event that a socket has not been manually closed, Python will automatically close it during the garbage collection process. However, relying on this automated closure is generally discouraged. An unexpected early closure of a socket may lead to issues, such as the counterpart socket processing requests at an inadequate speed. Consequently, it is essential to explicitly close the socket once the intended operations have been completed.

You can ensure that all necessary cleanup and termination procedures are performed, thereby preventing any possible connection issues, by explicitly closing the socket with the close function.

Tornado Framework

Tornado is an influential web framework in Python, along with an asynchronous networking library. It has been designed to meet the challenges of high-performance applications, including the handling of hundreds of simultaneous open connections. A key characteristic of Tornado is its non-blocking I/O framework, which facilitates the effective management of a large number of connections without relying on traditional thread-based concurrency methods.

The event-driven model forms the foundation of Tornado's non-blocking I/O, allowing for the asynchronous processing of requests and responses. Consequently, Tornado can proficiently oversee multiple connections using a single thread, instead of dedicating individual threads or processes to each connection. This technique significantly minimizes the expenses associated with context switching and thread synchronization, thereby enhancing both performance and scalability.

Tornado Framework over Normal Sockets

Tornado offers several benefits over traditional socket programming, making it a preferred choice for many developers:

  • Asynchronous I/O: Tornado is designed to manage numerous connections inside a single thread thanks to its asynchronous I/O architecture. As a result, there is no longer a requirement for thread-based parallelism, and the overhead of context switching and thread synchronization is decreased. As a result, Tornado can manage several connections at once while using fewer resources and performing better.
  • Scalability: Tornado is very scalable thanks to its non-blocking I/O design. Without many threads or processes, it can simultaneously handle thousands of open connections. Real-time apps and WebSockets are two examples of programs that demand great performance and must manage several concurrent clients.
  • Support for WebSockets: Tornado incorporates WebSockets, a well-liked technology for real-time communication between clients and servers. Tornado is perfectly suited for maintaining persistent WebSocket connections because of its asynchronous nature, enabling efficient and speedy real-time applications.
  • High-performance: Tornado is a high-performance framework thanks to its design and architecture. The Tornado can enable quicker response times and higher transactional performance by reducing the overhead associated with standard socket programming.
  • Comprehensive Features: Routing, template rendering, form handling, and authentication are just a few of the extensive capabilities and tools Tornado provides for creating online applications. While keeping its focus on asynchronous and high-performance networking, it offers a comprehensive framework for developing reliable and feature-rich web applications.
  • Community and ecology: The ecosystem of libraries and extensions for Tornado is expanding, and its development community is active. To increase their Tornado applications' functionality, developers may use existing libraries, access resources and tutorials, and receive help from the community.

Overall, Tornado is a favored choice for developing high-performance web applications and real-time communication systems, owing to its combination of an asynchronous I/O approach, scalability, and compatibility with WebSocket. This framework enables developers to build efficient and responsive applications that meet extensive networking demands.

Let us explore the subsequent illustration of a basic Tornado WebSocket.

Example -

Example

import tornado.ioloop
import tornado.web

class ApplicationHandler(tornado.web.RequestHandler):

    def get(self):
        self.message = message = """<html>
<head>
    <title>Tornado Framework</title>

</head>
<body
    <h2>Welcome to the Tornado framework</h2>
</body>
</html>"""
        self.write(message)

if __name__ == "__main__":
    application = tornado.web.Application([
        (r"/", ApplicationHandler),
    ])
    application.listen(5001)
    tornado.ioloop.IOLoop.instance().start()

Output:

Explanation:

In the above code,

  • We have defined the class ApplicationHandler which uses as the handler for request and return a response using the write
  • The main method is the entrance of the program.
  • The class web.Application creates the base for the web application and accepts a collection of handlers.
  • The Application listens on port 5000, and a client can communicate to this application using the same port.
  • The ioloop.IOLoop.instance.start function is used to create a nonblocking thread for an application.

In this article, we have explored the fundamental concepts of network programming with Python. We have outlined essential networking terminology and demonstrated the creation of a simple server and client. The realm of network programming is extensive and challenging to encapsulate in a single tutorial; however, we have endeavored to address all significant aspects related to network programming with Python.

Input Required

This code uses input(). Please provide values below: