Пример #1
0
    def recv_img(self, filename):
        """
        Receive an image packet by packet
        Saves image to specified file

        Parameters:
          filename - file location to save image
        """
        recv_data = b''  # packet of byte string data
        save_data = b''  # data to be saved to file
        img_not_recvd = True  # flag to indicate if image has been recieved
        exp_seq = 0  # expected sequence number initially 0
        pkt = Packet()
        self.err_flag = 0
        ack = Packet(-1, "ACK")  # make initial NAK

        # get image data from server until all data received
        while True:
            try:
                if img_not_recvd:
                    print("Server: Ready to receive image", flush=True)

                recv_data = self.server_socket.recv(self.pkt_size)

                pkt.pkt_unpack(recv_data)
                if pkt.seq_num != exp_seq or pkt.csum != pkt.checksum(
                        pkt.seq_num, pkt.data):
                    pass
                else:
                    save_data += pkt.data
                    ack = Packet(exp_seq, "ACK")
                    exp_seq += 1

                ack_pack = ack.pkt_pack()
                self.server_socket.sendto(ack_pack, self.client_addr)

                if img_not_recvd:
                    img_not_recvd = False  # img data began streaming if it reaches this point

            except socket.timeout:
                # if image not recieved yet, keep waiting
                if img_not_recvd:
                    pass
                # image has been recieved
                else:
                    # write data into a file
                    with open(filename, 'wb+') as server_img:
                        server_img.write(save_data)
                    print("Server: Received and saved image", flush=True)
                    break  # exit loop
Пример #2
0
    def send_img(self, filename):
        """
        Sends the image packet by packet

        Parameters:
          filename - file to send
        """
        recv_data = b''       # bytes for data received
        recv_pkt = Packet()   # init empty packet for received data
        read_data = b''       # byte string data read from file
        seq_num = 0           # init sequence number

        # open file to be sent
        print("Client: Sending image to Server")
        with open(filename, 'rb') as img:
            read_data = img.read(self.data_size)
            # pack
            send_pkt = Packet(seq_num=seq_num, data=read_data)
            packed = send_pkt.pkt_pack()

            # send data until end of file reached
            while read_data:
                self.client_socket.sendto(packed, self.server_addr)
                #print("Client: Sent:", send_pkt)

                # wait for ACK
                recv_data = self.client_socket.recv(self.pkt_size)
                recv_pkt.pkt_unpack(recv_data)

                #print("Client: Received message:", recv_pkt)

                # Received NAK or incorrect ACK
                if recv_pkt.seq_num != seq_num or recv_pkt.csum != recv_pkt.checksum(recv_pkt.seq_num, recv_pkt.data):
                    pass
                # ACK is OK, move to next data and sequence
                else:
                    #print("Client: got ok packet")
                    seq_num ^= 1
                    read_data = img.read(self.data_size)
                    # pack
                    send_pkt = Packet(seq_num=seq_num, data=read_data)
                    packed = send_pkt.pkt_pack()
Пример #3
0
    def send_img(self, filename):
        """
        Sends the image packet by packet

        Parameters:
          filename - file to send
        """
        recv_data = b''  # bytes for data received
        recv_pkt = Packet()  # init empty packet for received data
        read_data = b''  # byte string data read from file
        seq_num = 0  # init sequence number
        my_timer = Timer()  # Timer thread
        my_timer.set_time(0.05)  # set timer to 50 ms
        my_timer.stop()  # so timer doesn't start counting
        my_timer.start()  # start timer thread

        # open file to be sent
        print("Server: Sending image to client")
        start = time()
        with open(filename, 'rb') as img:
            read_data = img.read(self.data_size)
            # pack
            send_pkt = Packet(seq_num=seq_num, data=read_data)
            packed = send_pkt.pkt_pack()

            # send data until end of file reached
            while read_data:

                if (self.crpt_data_rate > 0 or self.crpt_ack_rate > 0
                        or self.pkt_loss_rate > 0 or self.ack_loss_rate > 0):
                    self.gen_err_flag()

                # corrupt 1 byte of the sent packet
                if self.crpt_data_rate > 0 and self.err_flag <= self.crpt_data_rate:
                    crptpacked = b"".join([packed[0:1023], b"\x00"])
                    self.server_socket.sendto(crptpacked, self.client_addr)
                elif self.pkt_loss_rate > 0 and self.err_flag <= self.pkt_loss_rate:
                    pass  # dont send anything
                else:
                    self.server_socket.sendto(packed, self.client_addr)

                my_timer.restart()
                if self.pkt_loss_rate > 0 and self.err_flag <= self.pkt_loss_rate:
                    while not my_timer.get_exception():
                        sleep(0.0001)
                else:
                    # wait for ACK
                    recv_data = self.server_socket.recv(self.pkt_size)

                if self.ack_loss_rate > 0 and self.err_flag <= self.ack_loss_rate:
                    while not my_timer.get_exception():
                        sleep(0.0001)
                else:
                    my_timer.stop()

                    # corrupt 1 byte of the recived ACK packet
                    if self.crpt_ack_rate > 0 and self.err_flag <= self.crpt_ack_rate:
                        recv_data = b"".join([recv_data[0:1023], b"\x00"])

                    recv_pkt.pkt_unpack(recv_data)

                    # Received NAK or incorrect ACK
                    if recv_pkt.seq_num != seq_num or recv_pkt.csum != recv_pkt.checksum(
                            recv_pkt.seq_num, recv_pkt.data):
                        pass
                    # ACK is OK, move to next data and sequence
                    else:
                        seq_num ^= 1
                        read_data = img.read(self.data_size)
                        # pack
                        send_pkt = Packet(seq_num=seq_num, data=read_data)
                        packed = send_pkt.pkt_pack()

        my_timer.kill()
        my_timer.join()
        end = time()
        print("Server: Time to send image:", end - start)
Пример #4
0
    def run(self):
        """
        Runs when Server process has started
        """
        print("Server: Started")
        i = 0  # index of timeouts

        while True:
            try:
                print("Server: Ready", flush=True)
                # get request and address from client
                msg = b''  # set message to empty string
                recv_data = b''  # set received data to empty string
                msg_pkt = Packet()  # init empty packet
                (recv_data,
                 self.client_addr) = self.server_socket.recvfrom(self.pkt_size)
                i = 0  # reset timeout index
                #print("got data")
                msg_pkt.pkt_unpack(recv_data)
                #print("Received message:", msg_pkt)

                if msg_pkt.csum != msg_pkt.checksum(msg_pkt.seq_num,
                                                    msg_pkt.data):
                    # send NAK
                    nak_seq = msg_pkt.seq_num ^ 0x01
                    ack = Packet(nak_seq, "ACK")
                    ack_pack = ack.pkt_pack()
                    self.server_socket.sendto(ack_pack, self.client_addr)
                else:
                    msg = msg_pkt.data.decode()
                    print("Server: Client request:", msg, flush=True)

            except socket.timeout:
                i = i + 1
                if (i < 6):
                    pass
                # if the server has waited through 6 timeouts (12 seconds), exit
                else:
                    print("Server: I'm tired of waiting", flush=True)
                    break

            # if any message recieved, then service it
            if msg:
                # ------------------ Send image to client ------------------
                if msg == "download":
                    print("Server: Send ACK")
                    ack = Packet(msg_pkt.seq_num, "ACK")
                    #print("ACK:", ack)
                    ack_pack = ack.pkt_pack()
                    #print(int.from_bytes(ack_pack[(len(ack_pack)-2):len(ack_pack)], byteorder='big', signed=False))
                    self.server_socket.sendto(ack_pack, self.client_addr)

                    # break
                    self.send_img(self.img_to_send)

                # ------------------ Get image from client ------------------
                elif msg == "upload":
                    print("Server: Send ACK")
                    ack = Packet(msg_pkt.seq_num, "ACK")
                    ack_pack = ack.pkt_pack()
                    self.server_socket.sendto(ack_pack, self.client_addr)

                    self.recv_img(self.img_save_to)

                # ------------------ Exit server process ------------------
                elif msg == "exit":
                    print("Server: Send ACK")
                    ack = Packet(msg_pkt.seq_num, "ACK")
                    ack_pack = ack.pkt_pack()
                    self.server_socket.sendto(ack_pack, self.client_addr)

                    print("Server: Exiting...")
                    break

                # ------------------ Handle invalid request ------------------
                else:
                    # send NAK
                    nak_seq = msg_pkt.seq_num ^ 0x01
                    ack = Packet(nak_seq, "ACK")
                    ack_pack = ack.pkt_pack()
                    self.server_socket.sendto(ack_pack, self.client_addr)

                    print("Server: Received invalid request:", msg)

        # close socket when finished
        self.server_socket.close()
Пример #5
0
    def send_img(self, filename):
        """
        Sends the image packet by packet

        Parameters:
          filename - file to send
        """
        recv_data = b''  # bytes for data received
        recv_pkt = Packet()  # init empty packet for received data
        read_data = b''  # byte string data read from file
        seq_num = 0  # init sequence number
        base = 0  # init base packet number
        window = []  # init window as empty list
        win_idx = 0  # index to item in window
        last_sent = None
        my_timer = Timer()  # Timer thread
        my_timer.set_time(0.1)  # set timer to 100 ms
        my_timer.stop()  # so timer doesn't start counting
        my_timer.start()  # start timer thread

        self.client_socket.settimeout(0)  # don't block when waiting for ACKs

        # open file to be sent
        print("Client: Sending image to server")
        # start = time()
        with open(filename, 'rb') as img:
            read_data = img.read(self.data_size)
            # pack
            send_pkt = Packet(seq_num=seq_num, data=read_data)
            packed = send_pkt.pkt_pack()

            # add first packet to window list
            window.append(packed)

            # send data until end of file reached
            while read_data or len(window) > 0:
                if my_timer.get_exception():
                    self.resend_window(window)
                    my_timer.restart()

                win_idx = len(window) - 1
                if seq_num < (base + self.N) and window[win_idx] != last_sent:
                    self.client_socket.sendto(window[win_idx],
                                              self.server_addr)
                    last_sent = window[win_idx]
                    if base == seq_num:
                        my_timer.restart()  # start timer
                    seq_num += 1

                # wait for ACK
                if recv_data:
                    recv_data = b''  # empty data buffer
                try:
                    recv_data = self.client_socket.recv(self.pkt_size)
                except socket.error as e:
                    if e == 10035:
                        pass

                if recv_data:
                    recv_pkt.pkt_unpack(recv_data)

                    # Received NAK
                    if recv_pkt.csum != recv_pkt.checksum(
                            recv_pkt.seq_num, recv_pkt.data):
                        pass
                    # ACK is OK
                    else:
                        base = recv_pkt.seq_num + 1  # increment base
                        window.pop(0)  # remove acked packet from window
                        if base == seq_num:
                            my_timer.stop()
                        else:
                            my_timer.restart()
                # Move to next data
                if len(window) < self.N and read_data:
                    read_data = img.read(self.data_size)
                    # pack
                    send_pkt = Packet(seq_num=seq_num, data=read_data)
                    packed = send_pkt.pkt_pack()
                    window.append(packed)  # add packet to window
                sleep(0.0001)

        # end = time()
        my_timer.kill()
        my_timer.join()
        self.client_socket.settimeout(5)  # reset timeout value
Пример #6
0
    def send_img(self, filename):
        """
    Sends the image packet by packet

    Parameters:
      filename - file to send
    """
        recv_data = b''  # bytes for data received
        recv_pkt = Packet()  # init empty packet for received data
        read_data = b''  # byte string data read from file
        seq_num = 0  # init sequence number
        snd_crpt_rate = 0  # packet corruption rate in percent
        crpt_flag = 1  # corruption flag
        snd_ackcrpt_rate = 0  # recived ACK corruption rate inpercent
        ackcrpt_flag = 1  # corruption flag for ACK

        # open file to be sent
        print("Server: Sending image to client")
        # start = time()
        with open(filename, 'rb') as img:
            read_data = img.read(self.data_size)

            # send data until end of file reached
            while read_data:
                # pack and send
                send_pkt = Packet(seq_num=seq_num, data=read_data)
                packed = send_pkt.pkt_pack()

                # Iteration to corrupt 2 bytes of the sent packet
                if crpt_flag <= snd_crpt_rate:
                    crptpacked = b"".join([packed[0:1023], b"\x00"])
                    self.server_socket.sendto(crptpacked, self.client_addr)
                    crpt_flag = crpt_flag + 1
                else:
                    crpt_flag = crpt_flag + 1
                    self.server_socket.sendto(packed, self.client_addr)
                if crpt_flag > 100:
                    crpt_flag = 1

                # wait for ACK
                recv_data = self.server_socket.recv(self.pkt_size)

                # Iteration to corrupt 2 bytes of the recived ACK packet
                if ackcrpt_flag <= snd_ackcrpt_rate:
                    recv_data = b"".join([recv_data[0:1023], b"\x00"])
                    ackcrpt_flag = ackcrpt_flag + 1
                else:
                    ackcrpt_flag = ackcrpt_flag + 1
                if ackcrpt_flag > 100:
                    ackcrpt_flag = 1

                recv_pkt.pkt_unpack(recv_data)

                # Received NAK or incorrect ACK
                if recv_pkt.seq_num != seq_num or recv_pkt.csum != recv_pkt.checksum(
                        recv_pkt.seq_num, recv_pkt.data):
                    pass
                # ACK is OK, move to next data and sequence
                else:
                    seq_num ^= 1
                    read_data = img.read(self.data_size)
Пример #7
0
    def recv_img(self, filename):
        """
        Receive an image packet by packet
        Saves image to specified file

        Parameters:
          filename - file location to save image
        """
        recv_data = b''  # packet of byte string data
        save_data = b''  # data to be saved to file
        img_not_recvd = True  # flag to indicate if image data hasn't started yet
        exp_seq = 0  # expected sequence number initially 0
        chunks = {}  # init dictionary of received data chunks
        pkt = Packet()

        # get image data from server until all data received
        while True:
            try:
                if (self.crpt_ack_rate > 0 or self.ack_loss_rate > 0):
                    self.gen_err_flag()

                if img_not_recvd:
                    print("Client: Ready to receive image", flush=True)

                recv_data = self.client_socket.recv(self.pkt_size)

                pkt.pkt_unpack(recv_data)
                if pkt.seq_num < exp_seq or pkt.csum != pkt.checksum():
                    pass
                elif pkt.seq_num > exp_seq:
                    if pkt.seq_num not in chunks.keys():
                        chunks[pkt.seq_num] = pkt.data
                else:
                    chunks[pkt.seq_num] = pkt.data
                    # increment expected sequence to highest received data
                    exp_seq += len(pkt.data)
                    while exp_seq in chunks.keys():
                        exp_seq += len(chunks[exp_seq])

                ack = Packet(src=self.client_port,
                             dst=self.server_port,
                             seq_num=0,
                             ack_num=exp_seq,
                             data=b'',
                             ctrl_bits=0x10)

                ack_pack = ack.pkt_pack()

                if (self.ack_loss_rate > 0
                        and self.err_flag <= self.ack_loss_rate):
                    pass
                elif (self.crpt_ack_rate > 0
                      and self.err_flag <= self.crpt_ack_rate):
                    ack_pack = b"".join([ack_pack[0:1023], b"\x01"])
                    self.client_socket.sendto(ack_pack, self.server_addr)
                else:
                    self.client_socket.sendto(ack_pack, self.server_addr)

                if img_not_recvd:
                    img_not_recvd = False  # img data began streaming if it reaches this point

            except socket.timeout:
                # if image not recieved yet, keep waiting
                if img_not_recvd:
                    pass
                # image has been recieved
                else:
                    break  # exit loop

        for chunk in sorted(chunks.keys()):
            save_data += chunks[chunk]
        # write data into a file
        with open(filename, 'wb+') as client_img:
            client_img.write(save_data)
        print("Client: Received and saved image", flush=True)
Пример #8
0
    def send_img(self, filename):
        """
        Sends the image packet by packet

        Parameters:
          filename - file to send
        """
        recv_data = b''  # bytes for data received
        recv_pkt = Packet()  # init empty packet for received data
        read_data = b''  # byte string data read from file
        seq_num = 0  # init sequence number
        base = 0  # init base packet number
        window = {}  # init window as empty dict
        dupl_cnt = 0  # count of duplicate acks
        my_timer = Timer()  # Timer thread
        my_timer.set_time(0.1)  # set timer to 100 ms
        my_timer.stop()  # so timer doesn't start counting
        my_timer.start()  # start timer thread
        rtt_start = {}

        self.client_socket.settimeout(0)  # don't block when waiting for ACKs

        # open file to be sent
        print("Client: Sending image to server")
        # start = time()
        with open(filename, 'rb') as img:
            read_data = img.read(self.data_size)
            # pack
            send_pkt = Packet(src=self.client_port,
                              dst=self.server_port,
                              seq_num=seq_num,
                              ack_num=0,
                              data=read_data,
                              ctrl_bits=0x00)
            next_pkt = send_pkt.pkt_pack()

            # add first packet to window list
            window[send_pkt.seq_num] = next_pkt

            # send data until all data acked
            while read_data or len(window) > 0:
                # Move to next data
                if len(window) < self.N and read_data:
                    read_data = img.read(self.data_size)
                    # pack
                    if read_data:
                        send_pkt = Packet(src=self.client_port,
                                          dst=self.server_port,
                                          seq_num=seq_num,
                                          ack_num=0,
                                          data=read_data,
                                          ctrl_bits=0x00)
                        next_pkt = send_pkt.pkt_pack()
                        window[send_pkt.
                               seq_num] = next_pkt  # add packet to window
                    else:  # no more data to be sent
                        next_pkt = None

                if next_pkt:
                    self.client_socket.sendto(next_pkt, self.server_addr)
                    next_pkt = None
                    rtt_start[send_pkt.seq_num] = time()
                    if base == seq_num:
                        my_timer.restart()  # start timer
                    seq_num += len(send_pkt.data)

                if my_timer.get_exception():
                    self.N = ceil(self.N / 2)
                    self.resend_lost(window, base)
                    rtt_start[base] = time()
                    my_timer.restart()

                # receive ACK
                if recv_data:
                    recv_data = b''  # empty data buffer
                try:
                    recv_data = self.client_socket.recv(self.pkt_size)
                except socket.error as e:
                    if e == 10035:
                        pass

                if recv_data:
                    recv_pkt.pkt_unpack(recv_data)

                    if recv_pkt.csum != recv_pkt.checksum():
                        pass
                    # ACK is OK
                    else:
                        rtt_end = time()
                        if recv_pkt.ack_num > base:
                            dupl_cnt = 0  # reset duplicate count
                            prev_base = base
                            base = recv_pkt.ack_num  # increment base
                            for pkt in sorted(window.keys(
                            )):  # remove acked packets from window
                                if pkt < base:
                                    window.pop(pkt)
                                else:
                                    break
                            if len(window) == 0:  # no unacked packets
                                my_timer.stop()
                            else:  # unacked packets remaining
                                my_timer.restart(
                                    self.est_timeout(rtt_end -
                                                     rtt_start[prev_base]))
                            self.N += 1
                        elif recv_pkt.ack_num == base:
                            dupl_cnt += 1
                        # received 3 duplicate ACKs
                        if dupl_cnt >= 3:
                            dupl_cnt = 0
                            self.N = ceil(self.N / 2)
                            self.resend_lost(window, base)
                            rtt_start[base] = time()
                            my_timer.restart()

                sleep(0.0001)

        # end = time()
        my_timer.kill()
        my_timer.join()
        self.N = 1  #reset window size
        self.est_rtt = 0.1  # reset estimated rtt
        self.dev_rtt = 0  # reset deviation
        self.client_socket.settimeout(1)  # reset timeout value
Пример #9
0
    def send_img(self, filename):
        """
        Sends the image packet by packet

        Parameters:
          filename - file to send
        """
        recv_data = b''  # bytes for data received
        recv_pkt = Packet()  # init empty packet for received data
        read_data = b''  # byte string data read from file
        seq_num = 0  # init sequence number
        base = 0  # init base packet number
        window = {}  # init window as empty dictionary
        dupl_cnt = 0  # count of duplicate acks
        my_timer = Timer()  # Timer thread
        my_timer.set_time(0.1)  # set timer to 100 ms
        my_timer.stop()  # so timer doesn't start counting
        my_timer.start()  # start timer thread
        rtt_start = {}
        window_list = []
        rtt_list = []
        new_timeout = 0.1

        self.server_socket.settimeout(0)  # don't block when waiting for ACKs

        # open file to be sent
        print("Server: Sending image to client")
        start = time()
        with open(filename, 'rb') as img:
            read_data = img.read(self.data_size)
            # pack
            send_pkt = Packet(src=self.server_port,
                              dst=self.client_port,
                              seq_num=seq_num,
                              ack_num=0,
                              data=read_data,
                              ctrl_bits=0x00)
            next_pkt = send_pkt.pkt_pack()

            # add first packet to window list
            window[send_pkt.seq_num] = next_pkt

            # send data until all data acked
            while read_data or len(window) > 0:
                if (self.crpt_data_rate > 0 or self.pkt_loss_rate > 0):
                    self.gen_err_flag()

                window_list.append(self.N)
                rtt_list.append(new_timeout)

                # Move to next data
                if len(window) < self.N and read_data:
                    read_data = img.read(self.data_size)
                    # pack
                    if read_data:
                        send_pkt = Packet(src=self.server_port,
                                          dst=self.client_port,
                                          seq_num=seq_num,
                                          ack_num=0,
                                          data=read_data,
                                          ctrl_bits=0x00)
                        next_pkt = send_pkt.pkt_pack()
                        window[send_pkt.
                               seq_num] = next_pkt  # add packet to window
                    else:  # no more data to be sent
                        next_pkt = None

                if next_pkt:
                    if self.crpt_data_rate > 0 and self.err_flag <= self.crpt_data_rate:
                        # corrupt 1 byte of the sent packet
                        crptpacked = b"".join([next_pkt[0:1023], b"\x00"])
                        self.server_socket.sendto(crptpacked, self.client_addr)
                    elif self.pkt_loss_rate > 0 and self.err_flag <= self.pkt_loss_rate:
                        pass  # dont send anything
                    else:
                        # send normally
                        self.server_socket.sendto(next_pkt, self.client_addr)
                    next_pkt = None
                    rtt_start[send_pkt.seq_num] = time()
                    if base == seq_num:
                        my_timer.restart()  # start timer
                    seq_num += len(send_pkt.data)

                if my_timer.get_exception():
                    self.N = ceil(self.N / 2)
                    self.resend_lost(window, base)
                    rtt_start[base] = time()
                    my_timer.restart()

                # receive ACK
                if recv_data:
                    recv_data = b''  # empty data buffer
                try:
                    recv_data = self.server_socket.recv(self.pkt_size)
                except socket.error as e:
                    if e == 10035:
                        pass

                if recv_data:
                    recv_pkt.pkt_unpack(recv_data)

                    # Received NAK
                    if recv_pkt.csum != recv_pkt.checksum():
                        pass
                    # ACK is OK
                    else:
                        rtt_end = time()
                        if recv_pkt.ack_num > base:
                            dupl_cnt = 0  # reset duplicate count
                            prev_base = base
                            base = recv_pkt.ack_num  # increment base
                            for pkt in sorted(window.keys(
                            )):  # remove acked packets from window
                                if pkt < base:
                                    window.pop(pkt)
                                else:
                                    break
                            if len(window) == 0:  # no unacked packets
                                my_timer.stop()
                            else:  # unacked packets remaining
                                new_timeout = rtt_end - rtt_start[prev_base]
                                my_timer.restart(self.est_timeout(new_timeout))

                            self.N += 1

                        elif recv_pkt.ack_num == base:
                            dupl_cnt += 1
                        # received 3 duplicate ACKs
                        if dupl_cnt >= 3:
                            dupl_cnt = 0
                            self.N = ceil(self.N / 2)
                            self.resend_lost(window, base)
                            rtt_start[base] = time()
                            my_timer.restart()

                sleep(0.0001)

        end = time()
        my_timer.kill()
        my_timer.join()

        with open("window_size.csv", 'w+', newline='') as win_csv:
            writer = csv.writer(win_csv, delimiter=',')
            writer.writerow(window_list)

        with open("rtt_times.csv", 'w+', newline='') as rtt_csv:
            writer = csv.writer(rtt_csv, delimiter=',')
            writer.writerow(rtt_list)

        self.N = 1  #reset window size
        self.est_rtt = 0.1  # reset estimated rtt
        self.dev_rtt = 0  # reset deviation
        self.server_socket.settimeout(5)  # reset timeout value
        print("Server: Time to send image:", end - start)