Untitled

 avatar
unknown
python
2 years ago
7.1 kB
5
Indexable
import socket
import select

def client_program():
    
    # Setting up the initial values for the window size and the window range
    n = 4
    win_start = 0
    win_end = win_start + n - 1
    
    # Obtaining the hostname and port number for establishing the socket connection
    host = socket.gethostname()
    port = 12366
    
    # Initializing variables to keep track of the sent frames and the current state of the transmission
    sender = []
    flag = 0
    
    # Creating a socket object and connecting to the server
    client_socket = socket.socket()
    client_socket.connect((host, port))
    
    # Printing the window size and prompting the user to enter a message
    print('Window Size == ', n)
    print(' Type "exit" to terminate connection ')
    message = input("Type anything and press enter to send data to server:  ")
    
    # Looping until the user enters 'exit'
    while message.lower().strip() != 'exit':
        
        # Printing a message indicating that frames are being dispatched
        print("\nDispatching frames...\n")
        
        # Checking the flag variable to determine whether to resend the first frame or send the next set of frames
        if flag == 0:
            for i in range(n):
                sender.append(win_start + i)
            for i in sender:
                print("Frame Number: ", i)
        else:
            print("Frame Number: ", win_start)
        
        # Converting the window start value to a string and sending it to the server
        msg = str(win_start)
        client_socket.send(msg.encode())
        
        # Using the select function to determine if any data has been received from the server
        ready = select.select([client_socket], [], [], 1)
        if ready[0]:
            # If data has been received, it is converted to an integer and checked to ensure it is an ACK for the correct frame
            data = client_socket.recv(1024).decode()
            ack = int(data)
            if ack not in sender:
                # If the ACK is not for the correct frame, the window start and end values are adjusted accordingly and the sent frames are removed from the sender list
                win_start = ack
                win_end = win_start + n - 1
                flag = 0
                for i in range(n):
                    sender.pop()
            else:
                # If the ACK is for the correct frame, only the window start value is adjusted and the flag variable is set to indicate that the first frame needs to be resent
                win_start = ack
                flag = 1
        else:
            # If a timeout occurs, a message is printed and the loop continues from the beginning
            print("Timeout occurred, Resending frames...")
            continue
        
        # Printing the ACK received from the server and prompting the user to enter another message
        print("------------------------------")
        print('Received ACK from the Server: ' + data)
        message = input("Type anything and press enter to send data to server:  ")
    
    # Closing the socket connection when the user enters 'exit'
    client_socket.close()

if __name__ == '__main__':
    client_program()




#---------------------server.py---------------------------------
import socket
import random

# Defining a function to implement the server program
def server_program():
   
    # Obtaining the hostname and port number for establishing the socket connection
    host = socket.gethostname()
    port = 12366  
    
    # Initializing variables to keep track of the expected frame number, the window size, and the window range
    exp = 0
    n = 4
    new = 1
    win_start = 0
    win_end   = win_start + n - 1
    
    # Creating a list to keep track of received frames
    receiver = []
    
    # Creating a socket object and binding it to the host and port number
    server_socket = socket.socket()  
    server_socket.bind((host, port))  
    
    # Setting up the server to listen for incoming connections
    server_socket.listen(2)
    conn, address = server_socket.accept()  
    print("Connected: ", str(address))
    
    # Looping until the connection is closed
    while True:

        try:
            # Attempting to receive data from the client
            data = conn.recv(1024).decode()
            
            # Checking if no data was received (connection was closed)
            if not data:
                break
        
        except:
            # If an error occurs, indicating packet loss, print a message and continue the loop
            print("Packet Loss Occured!\n")
            continue
        
        # Converting the received data to an integer
        rec = int(data)
        
        # Calculating the upper limit of the current window
        lim = rec + n - 1
        
        # Initializing variables to keep track of the number of frames received and the state of the transmission
        count = 0
        flag = 0
        ack = rec
        
        # Checking if a random number is less than or equal to 0.3 to simulate packet loss
        if random.random() <= 0.3:
            print("Packet Loss Occured!\nFrame: ", rec)
            continue
        
        # Generating a random number between 1 and 4 to simulate selective repeat
        randy = random.randint(1, 4)
        
        # Checking if this is the first frame received in the current window
        if new == 1 : 
            while(count != randy):
                # Generating a random frame number within the current window
                temp = random.randint(rec, lim)
                
                # Checking if the generated frame number has already been received
                if temp not in receiver:
                    print("Frame Number Received: ", temp)
                    count = count + 1
                    flag = 1 
                    receiver.append(temp)
        else :
            print("Frame Number Received: ", rec) 
            receiver.append(rec)
            flag = 1
        
        # Calculating the next expected ACK number
        if(flag == 1):
            for i in range(rec,lim+1):
                if i not in receiver:
                    ack = i
                    break
                ack = i+1
        
        # Sending the ACK to the client
        print("\nACK sent: ", ack) 
        print('-----------------------------------------')
        data = str(ack)
        conn.send(data.encode())  

        # Adjusting the window start and end values if the current window has been fully acknowledged
        if ack > win_end :
            win_start = ack
            win_end   = win_start + n - 1
            new = 1 
        else :
            new = 0 

    # Closing the connection when the loop is exited
    conn.close()  


if __name__ == '__main__':
    server_program()
Editor is loading...