def listen(self): if self.srcUDPPort is None: self.log("An attempt to listen an un unbound port was made...\n") raise Exception("Socket not bound") sys.exit(1) self.state = 'LISTENING' waitLimit = self.resetLimit * 100 self.log("Waiting for init packet...\n") while waitLimit: #receive INIT try: self.log("Calling recvfrom to see if we have anything...\n") theBytes, address = self.recvfrom(self.recvWindowSize) self.log("Recvfrom called....\n") packet = self.__reconstructPacket(data = bytearray(theBytes)) log("Packet has been reconstructed. We're in listen. Header: " + str(packet.header) + "\n") if packet is None: waitLimit -= 1 continue except socket.timeout: waitLimit -= 1 continue except Exception: waitLimit -= 1 continue else: log("Checking to see if packet isInit, in listen...\n") if (packet.isInit()): log("Packet is INIT; breaking out of while loop in listen...\n") break else: waitLimit -= 1 if not waitLimit: log("Socket timed out!\n") raise Exception('socket timeout') self.ackNum = packet.header['seqNum'] + 1 self.log("Setting destination RxPPort to " + str(packet.header['desPort'])) self.desRxPPort = packet.header['desPort'] self.desAddr = address[0] self.log("Setting destination UDP port to " + str(address[1])) self.desUDPPort = address[1] #Send Ack 1 waitLimit = self.resetLimit * 100 while waitLimit: try: #create packet flags = (False, False, True, False, False, False) initPacket = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = flags, winSize = self.recvWindowSize, ) self.sendto(initPacket.toByteArray(), (self.desAddr, self.desUDPPort)) data, address = self.recvfrom(self.recvWindowSize) packet = self.__reconstructPacket(data = bytearray(data)) if not packet: waitLimit -= 1 continue except socket.timeout: waitLimit -= 1 except Exception: waitLimit -= 1 else: if packet.isCnct(): break else: waitLimit -= 1 if not waitLimit: raise Exception('socket timeout') self.ackNum = packet.header['seqNum'] + 1 self.finalCnctAckNum = self.ackNum #send the second ACK flags = (False, False, True, False, False, False) initPacket = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = flags, winSize = self.recvWindowSize, ) try: self.sendto(initPacket.toByteArray(), (self.desAddr, self.desUDPPort)) except socket.timeout: self.sendto(initPacket.toByteArray(), (self.desAddr, self.desUDPPort)) except Exception: self.sendto(initPacket.toByteArray(), (self.desAddr, self.desUDPPort)) self.state = 'ESTABLISHED'
def recv(self, maxLength): if self.srcRxPPort is None: self.log("Socket already closed") if self.state != 'ESTABLISHED': self.log("Socket already closed") message = bytes() log("INTIIAL INSTANTIATED MESSAGE: " + message.decode('UTF-8') + "\n") log("INTIAL MESSAGE LENGTH: " + str(len(message))) resetsLeft = self.resetLimit while resetsLeft: try: data, address = self.recvfrom(self.recvWindowSize) except socket.timeout: print "timeout in recv" flags = (False, False, True, False, False, False) ackPacket = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = flags, winSize = self.recvWindowSize, ) self.sendto(ackPacket.toByteArray(), (self.desAddr, self.desUDPPort)) resetsLeft -= 1 continue except Exception: print "timeout in recv" flags = (False, False, True, False, False, False) ackPacket = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = flags, winSize = self.recvWindowSize, ) self.sendto(ackPacket.toByteArray(), (self.desAddr, self.desUDPPort)) resetsLeft -= 1 continue packet = self.__reconstructPacket(bytearray(data)) if not packet: flags = (False, False, True, False, False, False) ackPacket = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = flags, winSize = self.recvWindowSize, ) self.sendto(ackPacket.toByteArray(), (self.desAddr, self.desUDPPort)) resetsLeft -= 1 continue else: self.ackNum = packet.header['seqNum'] + 1 if self.ackNum > RxPacket.maxAckNum(): self.ackNum = 0 if packet.isAck(): resetsLeft -= 1 continue if packet.data: message += packet.data #log("Message so far is " + message.decode('UTF-8') + "\n") #log("Individual packet this time was " + packet.data.decode('UTF-8') + "\n") flags = (False, False, True, False, False, False) ackPacket = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = flags, winSize = self.recvWindowSize, ) try: self.sendto(ackPacket.toByteArray(), (self.desAddr, self.desUDPPort)) except socket.timeout: flags = (False, False, True, False, False, False) ackPacket = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = flags, winSize = self.recvWindowSize, ) self.sendto(ackPacket.toByteArray(), (self.desAddr, self.desUDPPort)) except Exception: flags = (False, False, True, False, False, False) ackPacket = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = flags, winSize = self.recvWindowSize, ) self.sendto(ackPacket.toByteArray(), (self.desAddr, self.desUDPPort)) if (packet.isEndOfMessage()): break if (packet.isFin()): flags = (False, False, True, False, False, False) ackPacket = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = flags, winSize = self.recvWindowSize, ) self.sendto(ackPacket.toByteArray(), (self.desAddr, self.desUDPPort)) self.__closePassive(ackPacket) break #superlog("Returning message of length: " + str(len(message))) #return message if not resetsLeft: raise Exception('Socket timeout') superlog("Returning message of length: " + str(len(message))) return message
def __closePassive(self, ackPacket): if self.srcRxPPort is None: self.socket.close() raise RxPException("Socket not bound") if self.state != 'ESTABLISHED': self.socket.close() raise Exception("Connection not established") fin_flags = (False, False, False, True, False, False) finPacket = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = fin_flags, winSize = self.recvWindowSize, ) self.seqNum += 1 if self.seqNum > RxPacket.maxSeqNum(): self.seqNum = 0 resetsLeft = self.resetLimit isFinAcked = False while resetsLeft and (not isFinAcked): self.sendto(finPacket.toByteArray(), (self.desAddr, self.desUDPPort)) try: data, address = self.recvfrom(self.recvWindowSize) packet = self.__reconstructPacket(data) if not packet: resetsLeft -= 1 except socket.timeout: resetsLeft -= 1 continue except Exception: resetsLeft -= 1 continue else: if (packet.isAck() and packet.header['ackNum'] == self.seqNum): isFinAcked = True if (packet.isFin()): ack_flags = (False, False, False, True, False, False) finPacket = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = fin_flags, winSize = self.recvWindowSize, ) self.sendto(finPacket.toByteArray(), (self.desAddr, self.desUDPPort)) self.socket.close() self = RxPSocket(self.srcRxPPort, self.debug) self.state = 'CLOSED'
def send(self, msg): superlog("We're sending: " + str(len(msg)) + " bytes.\n") if self.srcRxPPort is None: raise Exception("Socket not bound") if self.state != 'ESTABLISHED': raise Exception("Connection not established") dataQueue = deque() packetQueue = deque() sentQueue = deque() lastSeqNum = self.seqNum log("Fragmenting data, adding it to que...\n") #fragment data and add it to data queue for i in range(0, len(msg), RxPacket.getDataLength()): if (i + RxPacket.getDataLength() > len(msg)): dataQueue.append(bytearray(msg[i : ])) log("In send dataQue loop, adding: " + bytearray(msg[i : ]).decode('UTF-8') ) else: dataQueue.append(bytearray(msg[i : i + RxPacket.getDataLength()])) log("In send dataQue loop, adding: " + bytearray(msg[i : i + RxPacket.getDataLength()]).decode('UTF-8')) log("Constructing to data queue...\n") #construct packet queue from data queue #numPackQd = 0 for data in dataQueue: if data == dataQueue[0]: flags = (False, False, False, False, True, False) if data == dataQueue[-1]: flags = (False, False, False, False, False, True) else: flags = (False, False, False, False, False, False) packet = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = flags, winSize = self.recvWindowSize, data = data ) self.seqNum += 1 if self.seqNum >= RxPacket.maxSeqNum(): self.seqNum = 0 if packet.isAck(): sys.exit(0) packetQueue.append(packet) #numPackQd += 1 #print numPackQd log("Packet queue created...\n") log("Preparing to send packets...\n") numPackSent = 0 resetsLeft = self.resetLimit while packetQueue and resetsLeft: #send packets in send window window = self.sendWindowSize while window and packetQueue: packetToSend = packetQueue.popleft() if (packetToSend and not isinstance(packetToSend, int)) and (not packetToSend.isAck()): #log("Sending RxPPacket to IP: " + str(self.desAddr) + " and port + " + str(self.desUDPPort) + "...\n") self.sendto(packetToSend.toByteArray(), (self.desAddr, self.desUDPPort)) numPackSent+=1 #log("RxPPacket sent!\n") #log("RXP PACKET SIZE: " + str(len(packet.toByteArray()))) lastSeqNum = packetToSend.header['seqNum'] window -= 1 sentQueue.append(packet) else: continue try: data, address = self.recvfrom(self.recvWindowSize) handShakeFinishedCheck = self.__reconstructPacket(bytearray(data)) packet = self.__reconstructPacket(data = bytearray(data), checkAckNum = lastSeqNum) if not packet: sentQueue.reverse() packetQueue.extendleft(sentQueue) sentQueue.clear() resetsLeft -= 1 continue except socket.timeout: window = 1 resetsLeft -= 1 sentQueue.reverse() packetQueue.extendleft(sentQueue) sentQueue.clear() except Exception: window = 1 resetsLeft -= 1 sentQueue.reverse() packetQueue.extendleft(sentQueue) sentQueue.clear() else: window += 1 if (isinstance(packet, int)): while packet < 0 and sentQueue: packetQueue.appendleft(sentQueue.pop()) packet += 1 continue elif handShakeFinishedCheck.isAck() and handShakeFinishedCheck.header['ackNum'] == self.finalCnctAckNum: flags = (False, False, True, False, False, False) ackPacket = RxPacket( srcPort = self.srcRxPPort, desPort = self.desRxPPort, seqNum = self.seqNum, ackNum = self.ackNum, flagList = flags, winSize = self.recvWindowSize, ) self.sendto(ackPacket.toByteArray(), (self.desAddr, self.desUDPPort)) resetsLeft = self.resetLimit sentQueue.reverse() packetQueue.extendleft(sentQueue) sentQueue.clear() elif packet.isAck(): self.seqNum = packet.header['ackNum'] resetsLeft = self.resetLimit sentQueue.clear() if not resetsLeft: raise Exception('socket timeout')