def read(self): # Get length of data length = ByteBuffer(self.sock.recv(4)).read_int() # Read data return ByteBuffer(self.sock.recv(length))
def handle_incoming(self): buff = ByteBuffer(self.file_sock.sock.recv(self.length)) file_name = buff.read_string() new_name = buff.read_string() self.hub.file_event_handler.add_ignore(("move", file_name, new_name)) move_file(self.hub.directory + file_name, self.hub.directory + new_name)
def read_packet(self): # Read packet info into byte buffer buff = self.read() # this function will wait at "self.sock.recv" above until data is available to be read # this yield allows caller to perform actions before incoming packets are handled yield # Read ID and size id = buff.read() session = buff.read_string() # Create response to authentication authenticated = False if session == "": # No session provided authenticated = not self.needs_auth elif is_valid_session(session): # Session is valid authenticated = True # Send auth response self.write(ByteBuffer.from_bool(authenticated)) # Return if authentication was incorrect if not authenticated: return # Handle packet using packet handler handle_incoming_packet(id, self.hub)
def write(self, byte_buffer): # Send length of data self.sock.send(ByteBuffer.from_int(len(byte_buffer)).bytes()) # Send data self.sock.send(byte_buffer.bytes())
def connect(self): print("Trying to connect to {}".format(self.address)) # Try to create a session with the server if not self.validate(): return try: # Time to wait (in seconds) timeout = FileClient.TIMEOUT_INTERVALS[self.timeout_count] # Wait until the time has passed while (time.time() - self.last_attempt <= timeout): time.sleep(0.5) # Create socket and connect to server self.file_sock = FileSocket(None, self, self.account.session) self.file_sock.sock.connect((self.host, FileSocket.PORT)) # Send the session key self.file_sock.write(ByteBuffer.from_string(self.account.session)) # Check the validation response authenticated = self.file_sock.read().read_bool() # Server didn't think our session was valid if not authenticated: print("Could not authenticate with server") return # Reset reconnect variables self.last_attempt = 0 self.timeout_count = 0 # Mark client as connected self.connected = True print("Successfully connected") except (ConnectionRefusedError, socket.timeout): # The connection wasn't accepted... # Set the time of last attempt to current time self.last_attempt = time.time() # Time to wait (in seconds) timeout = FileClient.TIMEOUT_INTERVALS[self.timeout_count] print("Could not connect to server. Trying again in {} seconds".format(timeout)) # Move to the next wait time if possible if self.timeout_count < len(FileClient.TIMEOUT_INTERVALS) - 1: self.timeout_count += 1
def send_packet(self, packet=None): # Use IdlePacket if packet was specified if packet is None: packet = IdlePacket() # Don't print for IdlePacket if packet.id != 0: print("Sending packet: {}".format(packet.__class__.name)) buff = ByteBuffer() # Write packet ID and size buff.write(packet.__class__.id) # Check if we have a session to send (client) session = "" if self.session is not None: session = self.session buff.write_string(session) # Send the buffer on the connection self.write(buff) # Get the authentication response authenticated = self.read().read_bool() # Return if we aren't authenticated if not authenticated: print("Invalid server session") return # Send packet using packet handler packet.handle_outgoing(self.hub, self)
def process(self): # The last time we've spoken to the server last_ping = 0 while self.connected:#This should listen for file and server changes try: # Process packets in the buffer queue self.prepare_packets(self) # Send an idle packet if queue is empty and enough time has passed if (len(self.packet_queue) == 0 and time.time() - last_ping >= FileClient.PACKET_IDLE_TIME): self.packet_queue.append(IdlePacket()) # Check if we're sending any packets so we can still know after they're sent has_packet = not len(self.packet_queue) == 0 # Send all packets in queue while not len(self.packet_queue) == 0: self.file_sock.send_packet(self.packet_queue.pop()) self.file_sock.write(ByteBuffer.from_bool(not len(self.packet_queue) == 0)) # Server will only respond if we actually sent something if has_packet: # Read all packets from the server while (self.file_sock.read().read_bool()): with self.file_sock.read_packet(): pass # Set the last time we spoke to the server to the current time last_ping = time.time() except ConnectionResetError as e: # We've lost connection to the server self.connected = False print(e) break # Wait for a fourth of the PACKET_IDLE_TIME # This is to save system resources while still frequently updating if needed time.sleep(FileClient.PACKET_IDLE_TIME / 4)
def send_file(self, file_name): hub = self.hub data_left = get_file_size(hub.directory + file_name) # Send file name and size buff = ByteBuffer.from_string(file_name) buff.write_int(data_left) self.write(buff) # Update hub transfer status hub.transferring = { "direction": "send", "file_name": file_name, "file_size": data_left } hub.transfer_progress = 0 # Open file for reading file = open(hub.directory + file_name, mode='rb') # Keep sending file data until we've transferred the whole file while (data_left > 0): # determine chunk size chunk_size = FileSocket.KILOBYTE if data_left > FileSocket.KILOBYTE else data_left # Read chunk from file and send on connection self.sock.send(file.read(chunk_size)) # Update hub transfer progress hub.data_sent += chunk_size hub.transfer_progress += chunk_size data_left -= chunk_size # Close file file.close() # Update hub transfer status hub.files_sent += 1 hub.transferring = None
def handle_outgoing(self, hub, file_sock): buff = ByteBuffer.from_string(self.file_name) buff.write_string(self.new_name) file_sock.sock.send(buff.bytes())
def handle_outgoing(self, hub, file_sock): file_sock.write(ByteBuffer.from_string(self.file_name))