TCP Simulator Project Solution - CS3S661 Computer Networks Project

Verified

Added on  2023/04/23

|10
|2560
|360
Project
AI Summary
This project provides a TCP simulator implemented in Python, demonstrating the state transitions of TCP connections. It includes both a client and a server component, each managing different states such as CLOSED, LISTEN, SYN_SENT, SYN_RECEIVED, ESTABLISHED, FIN_WAIT1, FIN_WAIT2, TIME_WAIT, CLOSE_WAIT, and LAST_ACK. The code defines classes for each state and handles transitions based on events like SYN, ACK, FIN, and RST packets. The client initiates connections and closes them, while the server listens for incoming connections and manages their lifecycle. The implementation uses sockets to simulate network communication and state management to adhere to TCP protocol specifications. Desklib offers this project solution along with a wealth of other study resources to aid students in mastering computer networking concepts.
Document Page
from socket import socket
from sys import argv
from time import sleep
class State:
#This the abstract class
#this class provides the class for the TCP state
state = None
Context_Current = None
#constrctor for the class
def __init__(self, context):
self.Context_Current = context
def trigger(self):
return True
class StateContext:
# by using this class the state of the TCP is changes based on the defined states in the LIST
state_index = 0;
state_current = None
# list for available states
list_states =
["CLOSED","SYNSENT","ESTABLISHED","FINWAIT1","FINWAIT2","TIMEDWAIT"]
def setState(self, state_new):
try:
self.state_current = self.list_states[state_new]
self.state_index = state_new
self.state_current.trigger()
return True
except KeyError:
return False
#this method returns the state index through which state is identified
def getstate_index(self):
return self.state_index
class Transition:
def passive_open(self):
print ("Error!")
return False
def syn(self):
print ("Error!")
return False
def ack(self):
print ("Error!")
return False
def rst(self):
print ("Error!")
return False
def syn_ack(self):
print ("Error!")
return False
def close(self):
print ("Error!")
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
return False
def fin(self):
print ("Error!")
return False
def timeout(self):
print ("Error!")
return False
def active_open(self):
print ("Error!")
return False
class Closed(State, Transition):
'''
This the class written for the closed state
'''
#constructor for the class
def __init__(self, Context):
State.__init__(self, Context)
def active_open(self):
print("Active Open")
self.Context_Current.make_connection()
print("Making connection and SENDING SYN")
self.Context_Current.socket.send("SYN")
print("SYN SEND transitioning")
self.Context_Current.setState(1)
return True
def rst(self):
#Reset the object and close the connection
#return true if succeeded else return false
try:
self.Context_Current.socket.close() #attempt for terminating socket
self.connection_address = 0 #reset address attribute
return True
except: #no current connection
return False
def trigger(self):
print("CLOSED state")
try:
print("Reset connection")
self.Context_Current.rst()
except:
pass
return True
class SynSent(State, Transition):
'''
SynSent class
'''
def __init__(self, Context):
State.__init__(self, Context)
def rst(self):
print("Setting state to CLOSED from Transitioning")
Document Page
self.Context_Current.setState(0)
return True
def ack(self):
print("ACK is sending")
self.Context_Current.socket.send("ACK")
print("State is changed to ESTABLISHED from Transitioning")
self.Context_Current.setState(2)
return True
def timeout(self):
print("Timed Out")
self.Context_Current.socket.send("RST")
self.Context_Current.rst
return True
def trigger(self):
# in order to call the correct method, we
# receive the information in the trigger.
print("SYN SENT state")
command = self.Context_Current.socket.recv(1024)
if command == "SYNACK":
print("SYN + ACK")
self.Context_Current.ack()
elif command == "RST":
self.Context_Current.rst()
else :
self.Context_Current.timeout()
return True
class Established(State, Transition):
'''
Established class
'''
def __init__(self, Context):
State.__init__(self, Context)
def close(self):
print("sending FIN")
print("Changing state to FIN WAIT-1: Transitioning")
self.Context_Current.socket.send("FIN")
self.Context_Current.setState(3)
return True
def trigger(self):
print("ESTABLISHED State")
self.Context_Current.close()
return True
class FinWait1(State, Transition):
'''
FinWait1 class
'''
def __init__(self, Context):
State.__init__(self, Context)
Document Page
def ack(self):
print("Changing state to FIN WAIT-2 : Transitioning")
self.Context_Current.setState(4)
return True
def trigger(self):
print("FIN WAIT-1 state")
command = self.Context_Current.socket.recv(1024)
if command == "ACK":
print("ACK")
return self.Context_Current.ack()
else:
print("No ACK")
return True
class FinWait2(State, Transition):
'''
FinWait2 class is the fifth state in TCP client. It is waiting FIN from server,
which means that server sent all data and trying to close connection as well.
Once it got FIN, it would send ACK to server as a message about receiving FIN and
let server close first. It then will transfer to final state for waiting.
'''
def __init__(self, Context):
State.__init__(self, Context)
def ack(self):
print("Sending Ack")
self.Context_Current.socket.send("ACK")
print("Transition is made to TIMED WAIT")
self.Context_Current.setState(5)
return True
def trigger(self):
print("FIN WAIT-2 state")
command = self.Context_Current.socket.recv(1024)
if command == "FIN":
print("FIN")
self.Context_Current.ack()
else:
print("No FIN")
return True
class TimedWait(State, Transition):
'''
Time Wait class
'''
def __init__(self, Context):
State.__init__(self, Context)
def timeout(self):
print("Close connection")
self.Context_Current.setState(0)
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
def trigger(self):
print("TIMEDWAIT state")
return self.Context_Current.timeout()
class TCPClient(StateContext, Transition):
def __init__(self):
self.connection_address = 0
self.host = "127.0.0.1"
self.port = 5000
self.socket = None
self.list_states[0] = Closed(self)
self.list_states[1] = SynSent(self)
self.list_states[2] = Established(self)
self.list_states[3] = FinWait1(self)
self.list_states[4] = FinWait2(self)
self.list_states[5] = TimedWait(self)
self.setState(0)
def passive_open(self):
return self.state_current.passive_open()
def syn(self):
return self.state_current.syn()
def ack(self):
return self.state_current.ack()
def rst(self):
return self.state_current.rst()
def syn_ack(self):
return self.state_current.syn_ack()
def close(self):
return self.state_current.close()
def fin(self):
return self.state_current.fin()
def timeout(self):
return self.state_current.timeout()
def active_open(self):
return self.state_current.active_open()
def make_connection(self):
'''this method initiates an outbound connection'''
self.socket = socket()
try:
self.socket.connect((self.host, self.port))
self.connection_address = self.host
self.socket.settimeout(10)
except Exception as err:
print(err)
exit()
if __name__ == '__main__':
if len(argv) < 2:
print("Error: At least two arguments must be provided")
exit()
Document Page
client = TCPClient()
if argv[1] == "client":
client.active_open()
else:
client.close()
from socket import socket
from sys import argv
from time import sleep
class State:
state = None #here the abstract class is defined
Context_Current = None
def __init__(self, context):
self.Context_Current = context
def trigger(self): return True
class StateContext:
state_index = 0;
state_current = None
list_states =
["CLOSED","LISTEN","SYNRECVD","ESTABLISHED","CLOSEWAIT","LASTACK"]
#this method changes the state to the given new state
def setState(self, newstate):
try:
self.state_current = self.list_states[newstate]
self.state_index = newstate
self.state_current.trigger()
return True
except KeyError:
return False
#this method gives the state index
def getstate_index(self):
return self.state_index
class Transition:
def passive_open(self):
print ("Error!")
return False
def syn(self):
print ("Error!")
return False
def ack(self):
print ("Error!")
return False
def rst(self):
print ("Error!")
return False
def syn_ack(self):
print ("Error!")
return False
Document Page
def close(self):
print ("Error!")
return False
def fin(self):
print ("Error!")
return False
def timeout(self):
print ("Error!")
return False
def active_open(self):
print ("Error!")
return False
class Closed(State, Transition):
'''
Closed class
'''
def __init__(self, Context):
State.__init__(self, Context)
def passive_open(self):
print("transitioning to Listen and passive is open")
self.Context_Current.listen()
self.Context_Current.setState(1)
return True
def rst(self):
try:
self.Context_Current.connection.close()
self.connection_address = 0
return True
except:
return False
def trigger(self):
print("state is CLOSED")
try:
print("connection is reset")
self.Context_Current.rst()
except:
pass
return True
class Listen(State, Transition):
'''
Listen class
'''
def __init__(self, Context):
State.__init__(self, Context)
def syn_ack(self):
print("Here SYN + ACK is send")
self.Context_Current.connection.send("SYNACK")
print("SYN RECVD state is set")
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
self.Context_Current.setState(2)
def trigger(self):
print("LISTEN state")
command = self.Context_Current.connection.recv(1024)
if command == "SYN":
print("SYN")
return self.Context_Current.syn_ack()
else:
print("No SYN")
self.Context_Current.connection.send("RST")
return True
class SynRecvd(State, Transition):
'''
This is the class which is created for the sync received from the client
'''
def __init__(self, Context):
State.__init__(self, Context)
def ack(self):
print("Transitioning to ESTABLISHED")
self.Context_Current.setState(3)
def trigger(self):
print("SYN RECVD state")
command = self.Context_Current.connection.recv(1024)
if command == "ACK":
print("ACK")
return self.Context_Current.ack()
else:
print("No ACK")
return True
class Established(State, Transition):
'''
This class is designed for the connection established
'''
def __init__(self, Context):
State.__init__(self, Context)
def ack(self):
print("Sending ACK")
self.Context_Current.connection.send("ACK")
print("Transitioning to CLOSEWAIT")
self.Context_Current.setState(4)
def trigger(self):
print("ESTABLISHED State")
command = self.Context_Current.connection.recv(1024)
if command == "FIN":
print("FIN.")
return self.Context_Current.ack()
else:
Document Page
print("No FIN")
return True
class CloseWait(State, Transition):
'''
CloseWait class
'''
def __init__(self, Context):
State.__init__(self, Context)
def close(self):
print("Sending FIN")
self.Context_Current.connection.send("FIN")
print("Transitioning to LAST ACK")
self.Context_Current.setState(5)
return True
def trigger(self):
print ("CLOSE WAIT state")
try:
self.Context_Current.close()
except:
pass
return True
class LastAck(State, Transition):
'''
This is th class defined for the last acknowledge
'''
def __init__(self, Context):
State.__init__(self, Context)
def ack(self):
print("Transitioning to CLOSED state...")
self.Context_Current.setState(0)
return True
def trigger(self):
print("LAST ACK state")
command = self.Context_Current.connection.recv(1024)
if command == "ACK":
print("ACK")
self.Context_Current.ack()
else:
print("No ACK")
return True
class TCPServer(StateContext, Transition):
def __init__(self):
self.connection_address = 0
self.host = "127.0.0.1"
self.port = 5000
self.socket = None
Document Page
self.list_states[0] = Closed(self)
self.list_states[1] = Listen(self)
self.list_states[2] = SynRecvd(self)
self.list_states[3] = Established(self)
self.list_states[4] = CloseWait(self)
self.list_states[5] = LastAck(self)
self.setState(0)
def passive_open(self):
return self.state_current.passive_open()
def syn(self):
return self.state_current.syn()
def ack(self):
return self.state_current.ack()
def rst(self):
return self.state_current.rst()
def syn_ack(self):
return self.state_current.syn_ack()
def close(self):
return self.state_current.close()
def fin(self):
return self.state_current.fin()
def timeout(self):
return self.state_current.timeout()
def active_open(self):
return self.state_current.active_open()
def listen(self):
'''this method initiates a listen socket, only for server'''
self.socket = socket()
try:
self.socket.bind((self.host,self.port))
self.socket.listen(1)
self.connection, self.connection_address = self.socket.accept() #connection acceptance
return True
except Exception as err:
print(err)
exit()
if __name__ == '__main__':
if len(argv) < 2:
print("Error: At least two arguments must be provided")
exit()
server = TCPServer()
if argv[1] == "server":
server.passive_open()
else:
server.close()
chevron_up_icon
1 out of 10
circle_padding
hide_on_mobile
zoom_out_icon
[object Object]