def recv_process(self):
     while True:
         UDPsocket.setblocking(self, 0)
         try:
             reply = UDPsocket.recvfrom(self, bufsize=4096)
             if reply is not None:
                 result = payload_resolver(reply[0])
                 if not result.jug:
                     continue
             else:
                 continue
         except:
             time.sleep(0.5)
             continue
         try:
             pack = self.datas[0]
             address = reply[1]
         except IndexError:
             continue
         if address not in self.seq.keys():
             self.seq[address] = 0
             self.seq_ack[address] = 0
         if result.seq_ack is self.seq[address] + pack[0].len:
             print('\"' + str(pack[0].payload) + '\"' + 'send successfully!')
             self.seq[address] += pack[0].len
             self.datas.remove(pack)
             continue
         elif result.seq is self.seq_ack[address] and result.syn is 1:
             print('\"' + str(result.payload) + '\"' + 'receive successfully!')
             self.seq_ack[address] += result.len
             continue
         else:
             time.sleep(0.5)
             continue
    def __init__(self):
        # udt
        self.udpsocket = UDPsocket()

        # FSM variables
        self.window_size = Config.RFT_WINDOW_SIZE
        self.unacked_queue = queue.Queue(self.window_size)
        self.unsent_queue = queue.Queue()
        self.base_seq_num = 0
        self.ack_num = 0  # the expecting seq_num

        # timer
        self.timer = timeoutMonitor(self, Config.RDT_TIMEOUT,
                                    Config.RDT_TIMROUT_CHECKING_TIME)
        self.timer.start()

        # destination
        self.addr = None

        # receive thread
        self.receive_queue = queue.Queue()

        # flag
        self.SYN_blocked_queue = queue.Queue()

        # coding
        self.encoding = Config.DEFAULT_CODING

        # threads
        self.recv_thread = recv_thread(self)
        self.send_thread = send_thread(self)
        self.retransmit_on = False
示例#3
0
    def send(self, data, ADDR):
        address = ADDR
        print('send to ', address)
        packets = []
        seq_num = 0
        #data = data.encode(encoding='utf-8')
        #self.pkt_num = int(len(data)/PACKET_SIZE)+ 1
        self.set_pkt_num(int(len(data) / PACKET_SIZE) + 1)
        '''
            slice the data into packets and put them into the buffer
        '''
        for i in range(0, self.pkt_num):
            data_slice = data[i * PACKET_SIZE:(i + 1) * PACKET_SIZE]
            seq_bytes = seq_num.to_bytes(4, byteorder='little', signed=True)
            check_sum = socket._get_checksum(self, seq_bytes + data_slice)
            packets.append(make_pkt(seq_num, data_slice, check_sum))
            seq_num += 1
        next_seq = 0
        print(self.pkt_num)
        # start sender receive thread
        #_thread.start_new_thread(socket._sender_recv, (self,))
        #t.start()
        while (self.base < self.pkt_num):
            #print(base)
            #lock.acquire()
            #print(next_seq)
            # send all pkts in the window
            while next_seq < self.base + WINDOW_SIZE and next_seq < self.pkt_num:
                print('sending pkt ', next_seq)
                UDPsocket.send(UDPsocket, packets[next_seq], address)
                # if next sequence number is equal to base, start timer
                next_seq += 1
            if not send_timer.running():
                print('start timer')
                send_timer.start()
            # wait for ack or timeout. we now release the lock and _sender_recv thread can do modification
            while send_timer.running() and not send_timer.timeout():
                #lock.release()
                print("Waiting...")
                socket._sender_recv(self)
                #time.sleep(SLEEP_INTERVAL)
                #lock.acquire()
            # handle timeout
            if send_timer.timeout():
                print("Time out")
                send_timer.stop()
                # resend every packet from base
                next_seq = self.base
            #lock.release()
        print('======finish send========')

        for i in range(0, 5):
            time.sleep(SLEEP_INTERVAL)
            UDPsocket.send(UDPsocket, make_pkt(0, b'', 0), address)
            print('=======sender send empty packet==========')

        #socket.set_flag()
        self.base = 0
示例#4
0
 def _close_connection(self, conn) -> None:
     if self.connection:  # client
         UDPsocket.close(self)
     elif self.connections:  # server
         del self.connections[conn.client]
         if self.state == State.CLOSED and len(self.connections) == 0:
             UDPsocket.close(self)
     else:
         raise Exception("Illegal state")
示例#5
0
    def recv(self, ADDR):
        expected_num = 0
        address = ADDR
        global data_buffer
        while True:
            # get the next packet from sender
            '''
            print(socket.send_finish)
            if socket.send_finish == 1:
                socket.clear_flag()
                break
            '''
            #time.sleep(1)
            pkt = UDPsocket.recv(self, BUFFER_SIZE)
            if pkt is None:
                continue
            #print('recv ', len(pkt))
            seq_num, data, checksum = unpack(pkt)

            if checksum == 0 and seq_num == 0:
                print('recv empty packet finish recv')
                break

            print("recv packet ", seq_num)
            #print('original checksum ', checksum)
            pkt_checksum = socket._get_checksum(self, pkt[0:-2])
            #print('recv checksum ', pkt_checksum)

            is_corrupt = not (checksum == pkt_checksum)
            print('is corrupt ', is_corrupt)
            # send an ack
            if seq_num == expected_num and not is_corrupt:
                print("Got expected pkt ", seq_num)
                print('Sending ACK', expected_num, 'TO', address)
                data_buffer += pkt[4:-2]
                _data = expected_num.to_bytes(4,
                                              byteorder='little',
                                              signed=True)
                UDPsocket.send(
                    UDPsocket,
                    make_pkt(expected_num, b'',
                             socket._get_checksum(self, _data)), address)
                expected_num += 1
            elif seq_num > 0:
                # send ack on previous acked packet
                pre_expected_num = expected_num - 1
                _data = pre_expected_num.to_bytes(4,
                                                  byteorder='little',
                                                  signed=True)
                print('Sending dup ACK', expected_num - 1)
                UDPsocket.send(
                    UDPsocket,
                    make_pkt(pre_expected_num, b'',
                             socket._get_checksum(self, _data)), address)
        print('==========recv finished===========')
        return data_buffer
 def recvfrom(self):
     while True:
         UDPsocket.setblocking(self, 5)
         result = UDPsocket.recvfrom(self, bufsize=4096)
         if result is None:
             continue
         else:
             try:
                 data = payload_resolver(result[0])
             except:
                 continue
             address = result[1]
             if data.jug:
                 if address not in self.seq.keys():
                     self.seq[address] = 0
                     self.seq_ack[address] = 0
                 if data.seq is not self.seq_ack[address]:
                     re = payload(seq_ack=self.seq_ack[address])
                     UDPsocket.sendto(self, re.to_ascii(), address)
                     continue
                 else:
                     self.seq_ack[address] = data.seq + data.len
                     re = payload(seq_ack=self.seq_ack[address])
                     UDPsocket.sendto(self, re.to_ascii(), address)
                     break
             else:
                 if address not in self.seq.keys():
                     self.seq[address] = 0
                     self.seq_ack[address] = 0
                 re = payload(seq_ack=self.seq_ack[address])
                 UDPsocket.sendto(self, re.to_ascii(), address)
                 continue
     # print('Inside function: '+str(data.payload))
     return data.payload, address
示例#7
0
    def _sender_recv(self):
        print('start recv')
        #global base
        global send_timer
        pkt = None
        #global lock
        sleep_time = random.random()
        time.sleep(sleep_time)
        signal.signal(signal.SIGALRM, recv_timeout_handler)
        try:
            signal.alarm(2)
            pkt = UDPsocket.recv(self, BUFFER_SIZE)
            if pkt:
                signal.alarm(0)
        except RuntimeError as e:
            print("recv time out")
            signal.alarm(0)

        if pkt is None:
            return
        ack, _data, checksum = unpack(pkt)
        print('recv ack ', ack)
        pkt_checksum = socket._get_checksum(self, pkt[0:-2])
        is_corrupt = not (checksum == pkt_checksum)
        print('is_corrupt ', is_corrupt)
        #print('base', self.base)
        if not is_corrupt and ack >= self.base and checksum != 0:
            #lock.acquire()
            self.base = ack + 1
            print('base update ', self.base)
            #print('pkt num ', self.pkt_num)
            if self.base == self.pkt_num:
                return
            send_timer.stop()
 def send(self, data):
     message = data[0]
     address = data[1]
     bytes = message.to_ascii()
     UDPsocket.sendto(self, bytes, address)
class socket():
    # init
    def __init__(self):
        # udt
        self.udpsocket = UDPsocket()

        # FSM variables
        self.window_size = Config.RFT_WINDOW_SIZE
        self.unacked_queue = queue.Queue(self.window_size)
        self.unsent_queue = queue.Queue()
        self.base_seq_num = 0
        self.ack_num = 0  # the expecting seq_num

        # timer
        self.timer = timeoutMonitor(self, Config.RDT_TIMEOUT,
                                    Config.RDT_TIMROUT_CHECKING_TIME)
        self.timer.start()

        # destination
        self.addr = None

        # receive thread
        self.receive_queue = queue.Queue()

        # flag
        self.SYN_blocked_queue = queue.Queue()

        # coding
        self.encoding = Config.DEFAULT_CODING

        # threads
        self.recv_thread = recv_thread(self)
        self.send_thread = send_thread(self)
        self.retransmit_on = False


# callable method

    def set_encoding(self, encoding):
        self.encoding = encoding

    def bind(self, ip_and_port):
        self.addr = ip_and_port
        self.udpsocket.bind(ip_and_port)
        self.recv_thread.start()

    def _get_base_seq_num(self):
        rtn = self.base_seq_num
        return rtn

    def accpet(self):
        Debug.verbose_print("accept : Waiting for new connection on {}".format(
            self.addr))

        # Wait for a connecting request
        packet, addr = self.recv_packet()
        self.addr = addr
        self.send_thread.start()
        Debug.verbose_print("accept : Accept connection from {}".format(addr))

        #Send SYN_ACK_PACKET
        self.send_packet(
            Encoder.SYN_ACK_PACKET(),
            addr)  # SEQ_NUM=self._get_base_seq_num(), ACK_NUM=self.ack_num

        self.SYN_blocked_queue.get()
        Debug.verbose_print("accept : Successfully finish handshaking")
        self.ack_num = 1

    def close(self):
        self.recv_thread.terminate()
        self.send_thread.terminate()

    def connect(self, addr):
        self.addr = addr
        Debug.verbose_print("connect : Try to connect {}".format(addr))
        # Send SYN
        self.send_packet(
            Encoder.SYN_PACKET(),
            addr)  #SEQ_NUM=self._get_base_seq_num(), ACK_NUM=self.ack_num
        self.send_thread.start()

        # Receive SYN ACK
        data, addr = self.recv_packet()
        Debug.verbose_print("connect : Successfully finish handshaking")
        self.ack_num = 1

    def recv(self):
        packet, addr = self.recv_packet()
        if packet.SEG == 0:
            return packet.payload.decode(self.encoding)
        else:  # packet.SEG == 1
            rtn_payload = packet.payload
            while packet.SEG != 0:
                packet, addr = self.recv_packet()
                rtn_payload += packet.payload  #

            return rtn_payload.decode(self.encoding)

    def send(self, data: str):
        segment_size = Config.SEGMENT_SIZE
        total_len = len(data)

        if total_len < segment_size:
            self.send_packet(self._make_packet(data), self.addr)
        else:
            ptr = 0
            next_ptr = segment_size
            # data_list = list(data)
            seq_num = self._get_base_seq_num()
            while ptr < total_len:
                seg = 1
                if next_ptr >= total_len:  # This is the last packet
                    next_ptr = total_len
                    seg = 0

                self.send_packet(
                    self._make_packet(data[ptr:next_ptr],
                                      seq_num=seq_num,
                                      seg=seg), self.addr)

                seq_num += 1
                ptr = next_ptr
                next_ptr += segment_size

    def recv_packet(self):
        receive_bytes = self.receive_queue.get()
        return receive_bytes

    def recv_packet_toQueue(self):
        while True:  # Keep receiving until the packet is in order and not corrupted
            recv = self.udpsocket.recvfrom(Config.BUFSIZE)

            # 1. Packet loss -> receive again
            if recv == None:
                Debug.debug_print("recv_packet : Loss. receive again.")
                continue
            data, addr = recv

            # 2. Corrputed -> discard -> receive again
            if Encoder._isCorrupted(data):
                Debug.debug_print("recv_packet : corrupted, discard.")
                continue

            # 3. Out of order -> discard -> receive again
            packet = Decoder.Packet(data)
            Debug.debug_print(
                "recv_packet : (s:{}, a:{}) payload:{}, SYN={}, ACK={}".format(
                    packet.seq_num, packet.ack_num, packet.payload, packet.SYN,
                    packet.ACK))
            if packet.seq_num != 0xFFFF and packet.seq_num > self.ack_num:
                Debug.debug_print(
                    "recv_packet : s:{}. expecting {}, discard".format(
                        packet.seq_num, self.ack_num))

            # 4. already receive before -> send pure ack -> receive again
            elif packet.seq_num < self.ack_num:  #
                Debug.debug_print(
                    "recv_packet : s:{} is already received. expecting {}, discard"
                    .format(packet.seq_num, self.ack_num))
                if (packet.SYN == 0
                        and packet.ACK == 0) or (packet.SYN == 1
                                                 and packet.ACK == 1):
                    self.send_pure_ack()

            # successfully receive the right packet
            else:
                break

        Debug.debug_print(
            "recv_packet : successfully receive reilable packet. seq_num:{}".
            format(packet.seq_num))

        # ack an unacked packet if (ack_num - 1 equals to smallest base_seq_num)
        if packet.ack_num > self.base_seq_num:
            # if retransmission is going on, wait until it finishes.
            while True:
                time.sleep(0.01)
                if self.retransmit_on:
                    continue
                else:
                    break
            while self.base_seq_num != packet.ack_num:
                Debug.debug_print(
                    "recv_packet : base_seq_num:{}. received ack_num:{}, move window."
                    .format(self.base_seq_num, packet.ack_num))
                self.timer.start_timer()
                self._move_window()

        # pure ack
        if packet.ACK == 1 and packet.SYN == 0:
            if packet.ack_num == 1 and packet.seq_num == 0xFFFF:  # Only for handshaking sessions
                self.SYN_blocked_queue.put(0)
            Debug.debug_print("recv_packet : pure ack")
            return None  # Do not forward ack

        # If the packet is not an ACK and not a SYN packet. Send ACK to this packet
        # assert packet.seq_num == self.ack_num
        if (packet.SYN == 0 and packet.ACK == 0) or (packet.SYN == 1
                                                     and packet.ACK == 1):
            # expecting the next
            self.ack_num += 1
            self.send_pure_ack()

        Debug.debug_print("recv_packet : forward to upper layer.")
        return packet, addr  # deliver to the upper layer

    def _move_window(self):
        self.base_seq_num += 1

        if not self.unacked_queue.empty():
            pkt = Decoder.Packet(self.unacked_queue.get())
            Debug.debug_print("ack and dequeue seq_num:{}".format(pkt.seq_num))
        if not self.unsent_queue.empty():
            sending_pkt_byte = self.unsent_queue.get()
            self.unacked_queue.put(sending_pkt_byte)
            self.udpsocket.sendto(sending_pkt_byte, self.addr)
            #
            packet = Decoder.Packet(sending_pkt_byte)
            Debug.debug_print("send_packet : (s:{}, a:{}) payload:{}".format(
                packet.seq_num, packet.ack_num, packet.payload))

    def send_packet(self, packet_byte: bytes, addr):
        Debug.debug_print("Append s:{} to unsent_queue".format(
            Decoder.Packet(packet_byte).seq_num))
        self.unsent_queue.put(packet_byte)

    def send_packet_fromQueue(self):
        if self.unacked_queue.empty() and (not self.retransmit_on):
            while (not self.unacked_queue.full()) and (
                    not self.unsent_queue.empty()):
                sending_pkt_byte = self.unsent_queue.get()
                self.unacked_queue.put(sending_pkt_byte)
                self.udpsocket.sendto(sending_pkt_byte, self.addr)
                #
                packet = Decoder.Packet(sending_pkt_byte)
                Debug.debug_print(
                    "send_packet : (s:{}, a:{}) payload:{}".format(
                        packet.seq_num, packet.ack_num, packet.payload))

    def send_pure_ack(self):
        Debug.debug_print("direct send ACK, ack_num : {}".format(self.ack_num))
        self.udpsocket.sendto(
            Encoder.ACK_PACKET(SEQ_NUM=0xFFFF, ACK_NUM=self.ack_num),
            self.addr)

    def _retransmit(self):
        self.timer.start_timer()
        if self.unacked_queue.qsize() == 0:
            return None
        Debug.debug_print(
            "_retransmit : timeout. expecting:{}. {} unacked packet still in queue"
            .format(self.base_seq_num, self.unacked_queue.qsize()))
        cnt = self.unacked_queue.qsize()

        self.retransmit_on = True

        for _ in range(cnt):
            packet_bytes = self.unacked_queue.get()
            self.unacked_queue.put(packet_bytes)

            packet = Decoder.Packet(packet_bytes)
            Debug.debug_print("_retransmit : s:{}, a:{}".format(
                packet.seq_num, packet.ack_num))

            self.udpsocket.sendto(packet_bytes, self.addr)

        self.retransmit_on = False

    def _make_packet(self, data: str, seq_num=-1, seg=0):
        if seq_num == -1:
            seq_num = self._get_base_seq_num()
        Debug.debug_print("_make_packet : make new packet s:{}, a:{}".format(
            seq_num, self.ack_num))
        return Encoder.MAKE_PACKET(ACK=0,
                                   SYN=0,
                                   SEQ_NUM=seq_num,
                                   ACK_NUM=self.ack_num,
                                   payload=data,
                                   SEG=seg)