示例#1
0
    def rcv_pkg(self, ack_pkg:TCPPackage):
        if self.finished:
            return
        
        ack = ack_pkg.ack_number
        
        self._set_ertt_dev_ertt(ack)
        self._set_rws(ack_pkg.window_size)
        
        base_seq_num = self.base + self.base_seq_number

        if base_seq_num < ack:
            self.base = ack - self.base_seq_number
            self._handle_new_ack()
            if self.base >= self.next_to_send:
                self.timer.stop()
        elif self.rws:
            self._handle_dupl_ack()
            times = self.fast_retr.pop(ack,1)
            if times == 3:
                # Fast Retransmition
                log.info(f"FAST RTM ACK:{ack} {self.__conn._info()}")
                if not self.finished:
                    self._build_and_send_pkg(ack - self.base_seq_number)
            else:
                self.fast_retr[ack] = times + 1
示例#2
0
 def _reset_variables(self):
     log.info(f"SENDER STOP {self.__conn._info()}")
     self.finished = True
     self.data = None
     self.pkg_sending = None
     self.fast_retr = dict()
     self.ack_sent = dict()
示例#3
0
    def __send(self):
        while self.__running and self.base < len(self.data):
            last_to_send = min(len(self.data), self.base + min(self.cws, self.rws))
            while self.next_to_send < last_to_send:
                pkg_sent = self._build_and_send_pkg(self.next_to_send)
                self.next_to_send += len(pkg_sent.data)
            
            if not self.timer.running():
                self.timer.start()

            while self.timer.running() and not self.timer.timeout():
                time.sleep(0.05)
            
            if self.timer.timeout():
                if self.timer._duration > self.MAX_WAITING_TIME:
                    self.sender_error.append("Wait time reached max value")
                    break
                self.next_to_send = self.base
                self.timer.stop()
                if self.rws: # Space in recv buffer
                    self._handle_timeout()
                    self.timer.set_duration(self.timer._duration * 2) # Timeout double the interval
                    log.info(f"TIMEOUT {self.__conn._info()} {self.timer._duration}")
                else:
                    log.info(f"RCV BUF FULL {self.__conn._info()}")
                            
        self._reset_variables()
        self._next_scheduled()
示例#4
0
def my_send_data():
    conn = dial(address)
    data = b"123456789a123456789b123456789c123456789d123456789e123456789f123456789g"
    size = 10
    while data:
        pkg, data = data[:size], data[size:]
        len_send = send(conn, pkg)
        log.info(f"Sent {pkg[:len_send]}")
        data = pkg[len_send:] + data
    close(conn)
示例#5
0
 def _send_flow_update_ack(self, current_ack:int):
     log.info(f"FLOW CTRL ON {self._info()}")
     while not self.window_size and self.__flow_ack_active: # Wait for space in buffer
         time.sleep(0.5)
         
     while self.ack_number == current_ack and self.__flow_ack_active: # Wait for sender to restart send data
         self._send_ack() # Send ack to notify sender the available space
         time.sleep(self.FLOW_WAITING)
     self.__flow_ack_active = False
     log.info(f"FLOW CTRL OFF {self._info()}")
示例#6
0
 def start(self):
     """
     Start the TCP functionality.  
     Must be called before any other method
     """
     if not self.__running:
         self.__running = True
         self.recv_thread = Thread(target=self.demultiplex, name='TCP', daemon=True)
         self.recv_thread.start()
         log.info("TCP Started")
示例#7
0
 def end(self):
     """
     Release all TCP resources and close all connections
     """
     if self.__running:
         self.close_all()
         self.__running = False
         self.recv_thread.join(2)
         self.recv_sock.close()
         log.info("TCP Closed")
示例#8
0
def my_recv_data():
    server = listen(address)
    conn = accept(server)
    close(server)
    data = b''
    rcv_data = True
    while rcv_data:
        rcv_data = recv(conn, 1)
        log.info(f"Received {rcv_data}")
        data += rcv_data
    log.info(f"Final data {data}")
    close(conn)
示例#9
0
 def _send_no_conn_reply(self, package:TCPPackage):
     """
     Send a rst package to client
     """
     with ut.get_raw_socket() as s:
         # Change package information
         # Set rst flag to notify that no conn exist with the package address
         flags = ut.PacketFlags(False, True, False, False, False, False, False, False)
         info = ut.PacketInfo(package.dest_host, package.source_host, package.dest_port,
                              package.source_port, package.ack_number, package.seq_number,0,
                              flags, 0, package.window_size)
         package = TCPPackage(b"", info, True)
         s.sendto(package.to_bytes(),(package.dest_host, package.dest_port))
         log.info(f"RST Package sent {package._endpoint_info()}")
示例#10
0
 def _set_ertt_dev_ertt(self, ack:int):
     value = self.ack_sent.get(ack,None)
     if not value:
         return
     sent_time, sent_times = value
     if sent_times == 1:
         now = time.time()
         rtt = now - sent_time
         if self.ertt:
             self.ertt = (1-self.RTT_WEIGHT) * self.ertt + self.RTT_WEIGHT * rtt
             self.dev_ertt = (1 - self.DEV_ERRT_WEIGHT) * self.dev_ertt + self.DEV_ERRT_WEIGHT * abs(self.ertt - rtt)
         else:
             self.ertt = now - sent_time
             self.dev_ertt = 0
         self.timer.set_duration(self.timeout_duration)
         log.info(f"TIMER RST {self.timeout_duration} {self.__conn._info()}")
         self.ack_sent[ack] = [time,2] # In case of rereceive the ack the time is invalid
示例#11
0
 def demultiplex(self):
     """
     Redirects incoming packages to corresponding connection
     """
     while self.__running:
         data = self.recv_sock.recv(2048)
         package = TCPPackage(data)
         package = self._can_queue_data(package):
         if package:
             log.info(f"TCP recv package: {package._info()}")
             conn = self.conn_dict.get(package.dest_host, package.dest_port,
                                       package.source_host, package.source_port)
             server_conn = self.conn_dict.get_server(package.dest_host,package.dest_port)
             if conn:
                 conn.handle_pkg(package)
             elif server_conn and package.syn_flag:
                 conn = server_conn.server_handle_pkg(package)
                 if conn:
                     TCP.add_connection(conn)
示例#12
0
    def __send_pkg(self, pkg:TCPPackage):
        while self.__running and self.base < 1:
            self.__send_pkg_raw(pkg)
            
            if not self.timer.running():
                self.timer.start()

            while self.timer.running() and not self.timer.timeout():
                time.sleep(0.05)
            
            if self.timer.timeout():
                if self.timer._duration > self.MAX_WAITING_TIME:
                    self.sender_error.append("Wait time reached max value")
                    break
                self.timer.stop()
                self.timer.set_duration(self.timer._duration * 2) # Timeout double the interval
                log.info(f"TIMEOUT {pkg._endpoint_info()} {self.timer._duration}")
        
        self._reset_variables()
        self._next_scheduled()
示例#13
0
def client_test():
    conn = dial(address)
    log.info("Client Done")
    data = b'123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h'
    data_send_len = send(conn, data)
    log.info(f"Client Sended: {data_send_len} of {len(data)}")
    close(conn)
    log.info("Client Closed")
示例#14
0
def server_test():
    server = listen(address)
    client_con = accept(server)
    log.info("Server Done")
    data_recv = None
    data = b""
    while True:
        try:
            data = recv(client_con, 2048)
        except Exception:
            break
        log.info(f"Server Recv {data}")
        if data_recv == None:
            data_recv = b""
        data_recv += data
        
    log.info(f"Server Received: {data_recv} length:{len(data_recv)}")
    close(server)
    close(client_con)
    log.info("Client Server Closed")
示例#15
0
 def delete_server(self, host:str, port:int):
     log.info(f"Server Connection deleted: {host}:{port}")
     self.server_conn_dict.pop((host, port),None)
示例#16
0
 def state(self, value:str):
     log.info(f"{self.state}->{value} CWS:{self.cws} SST:{self.ssthr} DACK:{self.dupl_ack} {self.__conn._info()}")
     self.__state = value
示例#17
0
 def state(self, value:str):
     log.info(f"CHNG CON STATE {self.state}->{value} {self._info()}")
     if value == Conn.CLOSED and self.state != Conn.CLOSED:
         self.__close_pkg_sent = False # Flag for last conn empty pkg
     self.__state = value
示例#18
0
 def delete(self, source_host:str, source_port:int, dest_host:str, dest_port:int):
     log.info(f"Connection deleted: {source_host}:{source_port} -> {dest_host}:{dest_port}")
     self.conn_dict.pop((source_host, source_port, dest_host, dest_port),None)
示例#19
0
 def add_server(self, conn: Conn):
     host, port = conn.local_host, conn.local_port
     log.info(f"Server Connection added: {host}:{port}")
     self.server_conn_dict[host,port] = conn
示例#20
0
 def __send_pkg_raw(self, pkg:TCPPackage):
     log.info(f"SENT LEN:{len(pkg.data)} {pkg._info()}")
     self._set_expecting_ack(pkg.expected_ack)
     self.sock.sendto(pkg.to_bytes(), (pkg.dest_host, pkg.dest_port))
示例#21
0
 def add(self, conn: Conn):
     source_host, source_port, dest_host, dest_port = conn.local_host, conn.local_port, conn.dest_host, conn.dest_port
     log.info(f"Connection added: {source_host}:{source_port} -> {dest_host}:{dest_port}")
     self.conn_dict[source_host,source_port,dest_host,dest_port] = conn