Ejemplo n.º 1
0
 def terminate(self):
     while self.client_state != States.CLOSED:
         if self.client_state == States.ESTABLISHED:
             terminate_header = utils.Header(self.next_seq_num,
                                             self.last_received_seq_num + 1,
                                             syn=0,
                                             ack=1,
                                             fin=1)
             self.next_seq_num += 1
             send_udp(terminate_header.bits())
             self.update_state(States.FIN_WAIT_1)
         elif self.client_state == States.FIN_WAIT_1:
             recv_data, addr = sock.recvfrom(1024)
             fin_ack_header = utils.bits_to_header(recv_data)
             self.last_received_seq_num = fin_ack_header.seq_num
             if fin_ack_header.ack == 1:
                 self.update_state(States.FIN_WAIT_2)
         elif self.client_state == States.FIN_WAIT_2:
             recv_data, addr = sock.recvfrom(1024)
             fin_fin_header = utils.bits_to_header(recv_data)
             self.last_received_seq_num = fin_fin_header.seq_num
             if fin_fin_header.fin == 1:
                 terminate_ack_header = utils.Header(
                     self.next_seq_num,
                     self.last_received_seq_num + 1,
                     syn=0,
                     ack=1,
                     fin=0)
                 self.next_seq_num += 1
                 send_udp(terminate_ack_header.bits())
                 self.update_state(States.CLOSED)
         else:
             pass
Ejemplo n.º 2
0
    def terminate(self):
        if self.client_state == States.ESTABLISHED:
            # send FIN message
            fin_header = utils.Header(self.my_next_seq, 0, syn=0, ack=0, fin=1)
            send_udp(fin_header.bits())
            # update my seq
            self.my_next_seq += 1
            # update state
            self.update_state(States.FIN_WAIT_1)
        else:
            raise RuntimeError("invalid states for termination")

        # wait for ack
        if self.client_state == States.FIN_WAIT_1:
            recv_data, addr = sock.recvfrom(1024)
            header = utils.bits_to_header(recv_data)
            if header.ack == 1 and header.ack_num == self.my_next_seq:
                # update server seq
                self.server_next_seq = header.seq_num + 1
                # update client state
                self.update_state(States.FIN_WAIT_2)
            else:
                raise RuntimeError("invalid server ack")
        else:
            raise RuntimeError("invalid states for termination")

        # wait for server FIN and send back a ACK
        if self.client_state == States.FIN_WAIT_2:
            recv_data, addr = sock.recvfrom(1024)
            header = utils.bits_to_header(recv_data)
            if header.fin == 1:
                # update server seq
                self.server_next_seq = header.seq_num + 1
                # send back a ack
                ack_header = utils.Header(self.my_next_seq,
                                          self.server_next_seq,
                                          syn=0,
                                          ack=1,
                                          fin=0)
                send_udp(ack_header.bits())
                # update client seq
                self.my_next_seq += 1
                # update client state
                self.update_state(States.TIME_WAIT)
            else:
                raise RuntimeError("invalid server fin")
        else:
            raise RuntimeError("invalid states for termination")

        # wait for 2 maximum segment life time then close the client
        if self.client_state == States.TIME_WAIT:
            time.sleep(2 * MSL)

            self.my_next_seq = -1
            self.server_next_seq = -1
            self.update_state(States.CLOSED)
        else:
            raise RuntimeError("invalid states for termination")
Ejemplo n.º 3
0
 def handshake(self):
     while self.client_state != States.ESTABLISHED:
         if self.client_state == States.CLOSED:
             seq_num = utils.rand_int()
             self.next_seq_num = seq_num + 1
             syn_header = utils.Header(seq_num, 0, syn=1, ack=0, fin=0)
             # for this case we send only header;
             # if you need to send data you will need to append it
             send_udp(syn_header.bits())
             self.update_state(States.SYN_SENT)
         elif self.client_state == States.SYN_SENT:
             recv_data, addr = sock.recvfrom(1024)
             syn_ack_header = utils.bits_to_header(recv_data)
             self.last_received_seq_num = syn_ack_header.seq_num
             if syn_ack_header.syn == 1 and syn_ack_header.ack == 1:
                 ack_header = utils.Header(self.next_seq_num,
                                           self.last_received_seq_num + 1,
                                           syn=0,
                                           ack=1,
                                           fin=0)
                 self.next_seq_num += 1
                 send_udp(ack_header.bits())
                 self.update_state(States.ESTABLISHED)
     else:
         pass
Ejemplo n.º 4
0
 def receive_acks_sub_process_stop_and_wait(self, lst_rec_ack_shared):
     while True:
         recv_data, addr = sock.recvfrom(1024)
         header = utils.bits_to_header(recv_data)
         if header.ack == 1 and header.ack_num == lst_rec_ack_shared.value + 1:
             lst_rec_ack_shared.value = header.ack_num
             break
Ejemplo n.º 5
0
def recv_msg():
    try:
        data, addr = sock.recvfrom(1024)
        header = utils.bits_to_header(data)
        body = utils.get_body_from_data(data)
        return (header, body, addr)
    except socket.timeout:
        return (None, None, None)
Ejemplo n.º 6
0
 def receive_acks_sub_process_go_back_n(self, lst_rec_ack_shared):
     lra = lst_rec_ack_shared.value
     # a list marks which message is acked
     acked = [0] * (SENDER_WINDOW_SIZE + 1)
     # a pointer points to current window side
     cur = 0
     while True:
         recv_data, addr = sock.recvfrom(1024)
         header = utils.bits_to_header(recv_data)
         if header.ack == 1 and header.ack_num > lra and header.ack_num <= lra + SENDER_WINDOW_SIZE:
             # mark this ack
             acked[header.ack_num - lra] = 1
             # move the pointer if possible
             while cur < SENDER_WINDOW_SIZE and acked[cur + 1] == 1:
                 cur += 1
                 # reset lst_rec_ack
                 lst_rec_ack_shared.value += 1
             if cur == SENDER_WINDOW_SIZE:
                 # now we received all acks
                 break
Ejemplo n.º 7
0
  def send_reliable_message(self, message):
    count= 0
    MSS = 2

    # split the message into chunks
    msg = message.split()

    #seq number
    seq_num = utils.rand_int()

    # Create the header we attach to our message
    msg_header = utils.Header(seq_num, 0, syn = 0, ack = 1, fin = 0)

    # Send initial chunk
    chunk = msg[count:count + 3]
    chunk = ','.join(chunk[0:2])
    send_udp(msg_header.bits() + chunk.replace(",", " ").encode())
    count += 2
  
    while count <= 7:
      #handle seq / ack 
      recv_data, addr = sock.recvfrom(1024) #receive the data sent from the server
      msg_header = utils.bits_to_header(recv_data) #convert received data to header format
      firstseq = msg_header.seq_num  # first msg seq number
      if msg_header.seq_num == firstseq or msg_header.seq_num == subseq:  #check current seq numb from previous, make sure increments by 1
        chunk = msg[MSS:MSS + 3] # 
        chunk = ','.join(chunk[0:2])
        send_udp(msg_header.bits() + chunk.replace(",", " ").encode())
        count += 2
        MSS += 2
        subseq = msg_header.seq_num + 1
      else: #if seq are not incrementing correctly then send previous chunk again
        print(msg_header.seq_num) #just printing out the seq number
        MSS -= 2
        chunk = msg[MSS:MSS - 3] # 
        chunk = ','.join(chunk[0:2])
        send_udp(msg_header.bits() + chunk.replace(",", " ").encode())


    #handle stop and wait
    pass
Ejemplo n.º 8
0
 def send_reliable_message(self, message):
     # send messages
     # we loop/wait until we receive all ack.
     self.receive_acks()
     count = 0
     msg = message.split()
     while count <= 6:
         chunk = msg[count:count + 3]
         chunk = ','.join(chunk[0:2])
         chunk.replace(",", " ")
         print(chunk.replace(",", " "))
         try:
             recv_data, addr = sock.recvfrom(1024)
             ack_header = utils.bits_to_header(recv_data)
         except socket.timeout:
             self.next_seq_num -= MSS
             continue
         if ack_header.ack_num != self.next_seq_num:
             self.next_seq_num -= MSS
             continue
         self.last_received_seq_num = ack_header.seq_num
         count += 2
Ejemplo n.º 9
0
    def handshake(self):
        if self.client_state == States.CLOSED:
            seq_num = utils.rand_int()
            syn_header = utils.Header(seq_num, 0, syn=1, ack=0, fin=0)
            # for this case we send only header;
            # if you need to send data you will need to append it
            send_udp(syn_header.bits())
            # update client seq number
            self.my_next_seq = seq_num + 1
            self.update_state(States.SYN_SENT)
        else:
            raise RuntimeError("invalid states for start a handshake.")

        # we wait for server to send back a SYN-ACK message
        if self.client_state == States.SYN_SENT:
            recv_data, addr = sock.recvfrom(1024)
            header = utils.bits_to_header(recv_data)
            # server syn header should have both syn and ack fields
            # and the ack_num should be client next sequence number
            if header.ack == 1 and header.syn == 1 and header.ack_num == self.my_next_seq:
                self.server_next_seq = header.seq_num + 1
                self.last_received_ack = header.ack_num + 1
            else:
                raise RuntimeError(
                    "invalid server SYN-reply, handshake failed.")

            # we send back ACK message
            ack_header = utils.Header(self.my_next_seq,
                                      self.server_next_seq,
                                      syn=0,
                                      ack=1,
                                      fin=0)
            send_udp(ack_header.bits())
            # update my seq
            self.my_next_seq += 1
            # update state -> connection established on the client's perspective
            self.update_state(States.ESTABLISHED)
        else:
            raise RuntimeError("invalid states for waiting server SYN-reply.")
Ejemplo n.º 10
0
def chan_server():
    global sock_client, sock_server, wait_send, addr_client, round
    while True:
        # need to wait until initial client message sent
        # to server, otherwise socket from server
        # is not valid (so sock_server.recvfrom will error)
        while wait_send == 0:
            pass
        print('waiting on server response')
        data_server, addr_server = sock_server.recvfrom(1024)

        header = utils.bits_to_header(data_server)

        if round >= 2 and (header.ack == 1 and header.syn == 0
                           and header.fin == 0) and random.randint(1, 10) <= 3:
            print("DROPPING ACK FROM SERVER")
            continue

        print(addr_server)
        print('forwarding to client')
        time.sleep(sleep_v)
        sock_client.sendto(data_server, (UDP_IP, addr_client[1]))
        time.sleep(sleep_v)
        round = round + 1
Ejemplo n.º 11
0
def chan_client():
    global sock_client, sock_server, wait_send, addr_client
    while True:
        print('waiting on client')
        data_client, addr_client = sock_client.recvfrom(1024)

        header = utils.bits_to_header(data_client)

        print(addr_client)
        print(addr_client[0])  # ip
        print(addr_client[1])  # port
        time.sleep(sleep_v)

        # drop messages randomly, after connection established
        #if round >= 2 and random.randint(1,10) <= 3:
        if round >= 2 and (header.ack == 0 and header.syn == 0
                           and header.fin == 0) and random.randint(1, 10) <= 3:
            print("DROPPING MESSAGE FROM CLIENT")
            continue

        print('forwarding to server')
        sock_server.sendto(data_client, (UDP_IP, UDP_PORT_SERVER))
        time.sleep(sleep_v)
        wait_send = 1
Ejemplo n.º 12
0
def recv_msg():
    data, addr = sock.recvfrom(1024)
    header = utils.bits_to_header(data)
    body = utils.get_body_from_data(data)
    return (header, body, addr)
Ejemplo n.º 13
0
 def receive_acks_sub_process(self, lst_rec_ack_shared):
     while True:
         recv_data, addr = sock.recvfrom(1024)
         header = utils.bits_to_header(recv_data)
         if header.ack_num > lst_rec_ack_shared.value:
             lst_rec_ack_shared.value = header.ack_num