Creating a simple TCP server to receive a text file from a client


I wrote this program to setup a simple server that listens for connections on its IP address and a user defined port number. Here's a breakdown of how it works:

a. The server class is defined to represent the server. It has an __init__ method that initialises the server object with the IP address, port number, and variables for client address, connection, and socket.

b. The start_server method is responsible for starting the server. It creates a TCP socket using the socket.socket function, sets a timeout of 5 seconds for socket operations using settimeout, binds the socket to the specified IP address and port using bind, and starts listening for incoming connections using listen. If any errors occur during this setup process, they are caught and handled appropriately. Finally, the method calls the accept_connections method to start accepting connections.

c. The accept_connections method accepts incoming connections. It calls the accept method on the socket object, which blocks until a client connects. Once a connection is established, it enters a with statement to automatically handle cleanup of the connection. It receives data from the client using recv and prints it. Any exceptions that occur during this process are caught and handled, and the connection is closed afterwards.

d. The check_ip_port function is used to validate the provided IP address and port number. It uses a regular expression pattern to check if the IP address is in the correct format and if the port number is within the valid range of 1 to 65535.

e. The main function serves as the entry point of the program. It prompts the user to enter the port number and validates it using the check_ip_port function. Then, it creates an instance of the server class with the provided IP address and port number, and starts the server by calling the start_server method.

With the server up and running at socket 192.168.1.100:565, I used Netcat to send file.txt from a client on IP address 192.168.1.200. This file contained the words 'TEST DATA':

Server:
Start server on port: 565
[*] Server started on 192.168.1.100:565 [*]


Client:
nc 192.168.1.100 565 < file.txt

Server:
Client connected: ('192.168.1.200', 62664)
Data received: TEST DATA

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()

Enquiries

[email protected]

Copyright © 2023 - slash-root.com