def beginCommunication(self): self._receiver_socket = socket(AF_INET, SOCK_DGRAM) self._receiver_socket.bind(("127.0.0.1", self._receiver_port)) # Receive SYN UDP_segment, addr = self._receiver_socket.recvfrom(self._receiver_port) self._startTime = getTime() # start timer once communication begins receivedHeader = STPHeader(extractHeader(UDP_segment)) self.writeToLog("rcv", getTime() - self._startTime, receivedHeader.getType(), receivedHeader.seqNum(), len(extractContent(UDP_segment)), receivedHeader.ackNum()) # Send SYN ACK self.transmitACKPacket(1, True, addr) # Receive ACK UDP_segment, addr = self._receiver_socket.recvfrom(self._receiver_port) receivedHeader = STPHeader(extractHeader(UDP_segment)) self.writeToLog("rcv", getTime() - self._startTime, receivedHeader.getType(), receivedHeader.seqNum(), len(extractContent(UDP_segment)), receivedHeader.ackNum())
def terminateConnection(self): self._sender_socket.setblocking(1) finHeader = STPHeader(Sender.current_seq_number, 0, 0, 0, 1, 0, False) finPacket = STPPacket(finHeader, "") self.createUDPDatagram(finPacket) # wait for ACK message, addr = self.receive() # wait for FIN message, addr = self.receive() # send ACK ackHeader = STPHeader(Sender.current_seq_number, 0, 0, 1, 0, 0, False) ackPacket = STPPacket(finHeader, "") self.createUDPDatagram(ackPacket) self._log.write("Amount of (original) Data Transferred: " + str(self._dataTransferred) + "\n") self._log.write( "Number of Data Segments Sent (Excluding retransmissions): " + str(self._numSegmentsSent) + "\n") self._log.write( "Number of (all) Packets Dropped (by the PLD module): " + str(self._numDropped) + "\n") self._log.write("Number of Retransmitted Segments: " + str(self._numRetransmitted) + "\n") self._log.write("Number of Duplicate Acknowledgements received: " + str(self._dupAcksReceived) + "\n")
def terminateConnection(self, addr): # send ack self.transmitACKPacket(0, 0, addr) # send fin finHeader = STPHeader(0, 0, 0, 0, 1, 0, False) finPacket = STPPacket(finHeader, "") self._receiver_socket.sendto(str(finPacket).encode(), addr) self.writeToLog("snd", getTime() - self._startTime, finHeader.getType(), finHeader.seqNum(), 0, finHeader.ackNum()) # receive ACK self._receiver_socket.setblocking(1) ack_segment, addr = self._receiver_socket.recvfrom(self._receiver_port) receivedHeader = STPHeader(extractHeader(ack_segment)) self.writeToLog("rcv", getTime() - self._startTime, receivedHeader.getType(), receivedHeader.seqNum(), len(extractContent(ack_segment)), receivedHeader.ackNum()) self._log.write("Amount of (original) Data Received: " + str(self._dataReceived) + "\n") self._log.write("Number of Data Segments Received: " + str(self._numSegmentsReceived) + "\n") self._log.write("Number of duplicate segments received " + str(self._numDupSegmentsReceived) + "\n")
def receive(self): message, addr = self._sender_socket.recvfrom(self._buffer_size) packetHeader = STPHeader(extractHeader(message)) self.writeToLog("rcv", getTime() - self._startTime, packetHeader.getType(), packetHeader.seqNum(), len(extractContent(message)), packetHeader.ackNum()) return message, addr
def transmitACKPacket(self, ack_number, isSyn, clientAddress): ackHeader = STPHeader(Receiver.current_ack_num, ack_number, 1, isSyn, 0, 0, False) ackPacket = STPPacket(ackHeader, "") self._receiver_socket.sendto(str(ackPacket).encode(), clientAddress) self.writeToLog("snd", getTime() - self._startTime, ackHeader.getType(), ackHeader.seqNum(), 0, ackHeader.ackNum()) Receiver.current_ack_num += 1
def initSenderSocket(self): # create a UDP server socket self._sender_socket = socket(AF_INET, SOCK_DGRAM) # THREE WAY HANDSHAKE: # send syn firstHeader = STPHeader(Sender.current_seq_number, 0, 0, 1, 0, 0, False) Sender.current_seq_number += 1 firstPacket = STPPacket(firstHeader, "") self.createUDPDatagram(firstPacket) # wait for a syn-ack #message, addr = self._sender_socket.recvfrom(self._buffer_size) message, addr = self.receive() # send ack ackHeader = STPHeader(2, 1, 1, 0, 0, 0, False) ackPacket = STPPacket(ackHeader, "") self.createUDPDatagram(ackPacket)
def communicate(self): self._receiver_socket.setblocking(0) received_packets = {} # Buffer for out-of-order received packets next_expected = 1 while True: # tries to get a packet - either DATA or FIN try: UDP_segment, addr = self._receiver_socket.recvfrom( self._receiver_port) receivedHeader = STPHeader(extractHeader(UDP_segment)) self.writeToLog("rcv", getTime() - self._startTime, receivedHeader.getType(), receivedHeader.seqNum(), len(extractContent(UDP_segment)), receivedHeader.ackNum()) header = STPHeader(extractHeader(UDP_segment)) if header.isFin(): # Connection terminating! self.terminateConnection(addr) break seqNum = header.seqNum() if (seqNum in received_packets.keys()): self._numDupSegmentsReceived += 1 else: self._dataReceived += len(extractContent(UDP_segment)) received_packets[seqNum] = UDP_segment self._numSegmentsReceived += 1 if (seqNum == next_expected): next_expected = int(seqNum) + int( len(extractContent(UDP_segment))) while next_expected in received_packets.keys(): next_expected += int( len(extractContent( received_packets[next_expected]))) self.transmitACKPacket(next_expected, 0, addr) except: pass self.writeAllPackets(received_packets)
def createSTPPackets(self): data = "" with open(self._filename, 'r') as f: for line in f.read(): data += line # split all the data up into packets stp_packets = [] i = 0 while i < len(data): curr_packet_data = data[i:i + self._MSS] header = STPHeader(Sender.current_seq_number, 0, 0, 0, 0, 1, False) stp_packet = STPPacket(header, curr_packet_data) stp_packets.append(stp_packet) Sender.current_seq_number += len(curr_packet_data) i += self._MSS return stp_packets
def sendPackets(self, stp_packets): sendbase = 0 # earliest not acked packet next_seq_num = 0 # earliest not sent packet dupAcks = {} # To store duplicate ACKs while sendbase < len(stp_packets): # # when window finished, send all packets in this new window if sendbase == next_seq_num: for i in range(0, (self._MWS / self._MSS)): if (sendbase + i >= len(stp_packets)): break self._dataTransferred += len(stp_packets[sendbase + i]._data) self._numSegmentsSent += 1 self.PLDModule(stp_packets[sendbase + i]) next_seq_num += 1 self._timer = getTime() # try to get an ACK: self._sender_socket.setblocking(0) isAck = False ackNum = 0 try: message, addr = self.receive() header = STPHeader(extractHeader(message)) isAck = header.isAck() ackNum = header.ackNum() except: # no packet right now pass if isAck: # received an ack if (ackNum > stp_packets[sendbase]._header.seqNum()): i = 0 found = 0 dupAcks[ackNum] = 1 for packet in stp_packets: if packet._header.seqNum() == ackNum: found = i i += 1 if found != 0: sendbase = found lastPack = stp_packets[len(stp_packets) - 1] if ackNum == lastPack._header.seqNum() + len( lastPack._data): break #self._timer = getTime() if (sendbase < next_seq_num): self._timer = getTime() else: dupAcks[ackNum] += 1 self._dupAcksReceived += 1 if (dupAcks[ackNum] >= 3): # Fast retransmit! dupAcks[ackNum] = 0 self._numRetransmitted += 1 for packet in stp_packets: if packet._header.seqNum() == ackNum: self.PLDModule(packet) self._timer = getTime() elif getTime() - self._timer >= self._timeout: # if timeout self._numRetransmitted += 1 self.PLDModule(stp_packets[sendbase]) self._timer = getTime()