Complete Code

import socket  # Import the socket module for network communication
import re  # Import the re module for regular expression matching

class server():  # Define the server class
    def __init__(self, ip, port):
        self.ip = ip  # Store the IP address
        self.port = port  # Store the port number
        self.addr = None  # Initialise the client address variable
        self.conn = None  # Initialise the connection variable
        self.s = None  # Initialise the socket variable
        
    def start_server(self):  # Method to start the server
        try:
            self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # Create a TCP socket
            self.s.settimeout(5)  # Set a timeout of 5 seconds for socket operations
            self.s.bind((self.ip, self.port))  # Bind the socket to the specified IP address and port
            self.s.listen(1)  # Listen for incoming connections
            print("[*] Server started on " + str(socket.gethostbyname(socket.gethostname())) + ":" + str(self.port) + " [*]")  # Print server started message
            self.accept_connections()  # Start accepting connections
        except socket.timeout:  # Handle socket timeout exception
            print("Timeout: No connections received.")
        except Exception as err:  # Handle other exceptions
            print("Error creating socket: " + str(err))
            self.s.close()  # Close the socket in case of an error
        finally:
            pass

    def accept_connections(self):  # Method to accept connections
        self.conn, self.addr = self.s.accept()  # Accept a connection
        with self.conn:  # Use the connection in a "with" statement for automatic cleanup
            print("Client connected: " + str(self.addr))  # Print client connected message
            try:
                data = self.conn.recv(1024)  # Receive data from the client
                print("Data received: " + data.decode())  # Print the received data
            except Exception as err:  # Handle exceptions during data receive
                print("Error: " + str(err))
            finally:
                self.conn.close()  # Close the connection

def check_ip_port(ip, port):  # Function to check if the IP address and port are valid
    pattern = r'^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$'  # Regular expression pattern for IP address
    if re.match(pattern, ip) and 1 <= port <= 65535:  # Check if the IP address and port are valid
        return True  # Return True if valid
    return False  # Return False if not valid

def main():  # Main function to start the server
    while True:
        ip = socket.gethostbyname(socket.gethostname())  # Get the IP address of the local machine
        port = int(input("Start server on port: "))  # Prompt the user to enter the port number
        if check_ip_port(ip, port):  # Validate the IP address and port
            break
        print("Please enter a port 1-65535.")
    
    s = server(ip, port)  # Create a server instance
    s.start_server()  # Start the server

if __name__ == '__main__':
    main()