def answer_to_question(self, question, EOM): answer_to_question = answer(question) # tell the user what's happening print("----------------------------------------") print("Question received: {}".format(question)) print("Answer: {}".format(answer_to_question)) if len(answer_to_question) > 64: print("handle sending of a multipart message") first_part_of_the_answer = answer_to_question[:64].encode('utf-8') second_part_of_the_answer = answer_to_question[64:].encode('utf-8') print(first_part_of_the_answer) print(second_part_of_the_answer) first_answer_packed = struct.pack('!??HH64s', EOM, True, len(first_part_of_the_answer), len(second_part_of_the_answer), first_part_of_the_answer) second_answer_packed = struct.pack('!??HH64s', EOM, True, len(second_part_of_the_answer), 0, second_part_of_the_answer) self.send_udp_message_to_host(first_answer_packed) print("Sent: ") self.pretty_print_packed_msg(first_answer_packed) self.send_udp_message_to_host(second_answer_packed) print("Sent: ") self.pretty_print_packed_msg(second_answer_packed) else: byte_answer = answer_to_question.encode('utf-8') packed_answer = struct.pack('!??HH64s', EOM, True, len(byte_answer), 0, byte_answer) print("Sent:") self.pretty_print_packed_msg(packed_answer) self.send_udp_message_to_host(packed_answer)
def run(self): # Continue only if we have valid server information if self.server_info: self.logger.info('Running...') if not self.tcp_client.connection_request(10000, 'MI'): self.logger.info('Unable to connect to server') return 0 # Get connection parameters from TCP client server_params = self.tcp_client.get_server_params() # server_params = {} # server_params['address'] = self.config.server_address # server_params['udp_port'] = self.config.server_port # Initialize UDP server parameters and start listening self.logger.info('Starting UDP server...') self.udp_client.set_server_info(server_params['address'], server_params['udp_port']) self.udp_client.set_listen_port(10000) self.udp_client.init_socket() self.udp_client.send('HELO') while True: msg, source = self.udp_client.get_next_message() self.logger.info("Received '%s'" % msg) if msg: if self.udp_client.eom_received: self.logger.debug('EOM received') break a = answer(msg) if a: self.logger.info("Sending '%s'" % a) self.udp_client.send(a) else: self.logger.info('No answer, sending NACK') self.udp_client.send_nack() else: self.logger.info('Empty message, sending NACK') self.udp_client.send_nack() self.udp_client.close() return 0
def start(): global ENCODING, SERVER_IP, SERVER_TCP_PORT, CLIENT_UDP_PORT, SERVER_KEY_COUNTER, NUM_KEYS SERVER_IP, SERVER_TCP_PORT = parsing.get_ip_and_port() if SERVER_IP == "" or SERVER_TCP_PORT == -1: return if use_encryption(): generate_encryption_keys() ENCODING = "latin-1" vprint("Server IP address: {} TCP port: {}".format(SERVER_IP, SERVER_TCP_PORT)) UDP_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) UDP_sock.settimeout(RECV_WAIT_TIME) CLIENT_UDP_PORT = bind_socket(UDP_sock, 10000, 10100) TCP_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if not TCP_handshake(TCP_sock): return TCP_sock.shutdown(socket.SHUT_RDWR) #Start UDP vprint("(UDP) Starting UDP communication.") packets = create_UDP_packets(False, True, "Ekki-ekki-ekki-ekki-PTANG.") vprint("(UDP) Server: {}".format((SERVER_IP, SERVER_UDP_PORT))) send_UDP_packets(UDP_sock, packets) vprint("(UDP) Sent initial message.\n") recvbuf = [] while True: vprint("(UDP) Waiting to receive...") try: recv_data, conn_info = UDP_sock.recvfrom(128) except socket.timeout: print("(UDP) No data received for {} seconds, shutting down.".format(RECV_WAIT_TIME)) break #Check ip and port if conn_info[0] != SERVER_IP or conn_info[1] != SERVER_UDP_PORT: request_UDP_resend(UDP_sock, "Server address and/or port mismatch.") continue try: EOM, ACK, content_length, remaining_data_length, content_raw = struct.unpack(UDP_PACKET_FORMAT, recv_data) except struct.error: SERVER_KEY_COUNTER += 1 request_UDP_resend(UDP_sock, "Received invalid packet from server.") continue vprint("(UDP) Received:\n\tEOM: {}\n\tACK: {}\n\tMessage length: {}\n\tRemaining data: {}\n\tRaw content: {}".format(EOM, ACK, content_length, remaining_data_length, content_raw)) if EOM: print("Server: {}".format(content_raw.decode(ENCODING))) break #Attempt to decrypt the server's message if use_encryption() and have_server_keys(): vprint("Decrypting with server key({}):{}".format(SERVER_KEY_COUNTER, SERVER_KEYS[SERVER_KEY_COUNTER])) content = encryption.decrypt(content_raw.strip(b"\x00").decode(ENCODING), SERVER_KEYS[SERVER_KEY_COUNTER]) SERVER_KEY_COUNTER += 1 if content == "BADMSG": request_UDP_resend(UDP_sock, "Could not decrypt message.") continue vprint("Decrypted: {}".format(content)) else: content = content_raw.strip(b"\x00").decode(ENCODING) #Compare given message length to actual message length if content_length != len(content): request_UDP_resend(UDP_sock, "Message length field does not match actual message length.") continue recvbuf.append(content) if remaining_data_length > 0: continue #Check for a valid answer content_full = "".join(recvbuf) recvbuf = [] response = answer(content_full) if response == "": request_UDP_resend(UDP_sock, "Did not find an answer for the server's question.") continue print("Server: {}".format(content_full)) print("Client: {}".format(response)) packets = create_UDP_packets(False, True, response) send_UDP_packets(UDP_sock, packets) TCP_sock.close() UDP_sock.close()
if count > 1: question = question.split('?') answers = "" x = count for n in range(x): _question = question[n] + "?" print "Question" print _question answ = answer(_question) print "\nOur answer:" print answ answers = answers + answ #crypted_answ = encryption.encrypt(answ, key_table[i+1]) #print crypted_answ #data = struct.pack("!??HH64s", False, True, len(answ), 0, crypted_answ) #sUDP.sendto(data, ((host, port))) #print "sent: " + data i = i + 1
def main(): #Komentoriviargumenttien syotto, seka mahdollinen HELP-tulostus, jos argumentteja ei ole oikea maara if len(sys.argv) < 2: print "HELP: Please give server address and port as command-line arguments." print "Server address should be ii.virtues.oulu.fi" print "Please give port number in range of 10000-10100" print "Proper command should be in form: python program.py server port" sys.exit(1) else: print "Arguments received!" addr = str(sys.argv[1]) tcp_port = int(sys.argv[2]) host_ip = socket.gethostbyname(addr) #Luodaan TCP- ja UDP-socket tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #Etsitaan oikea portti valilta 10000-10100 for bind_port in range(10000, 10100): try: udp_socket.bind(("", bind_port)) break except udp_socket.error: #Annetaan virhe, mikali porttia ei ole kaytettavissa. print "Couldn't bind port" tcp_socket.connect((host_ip, tcp_port)) #Lahetetaan TCP:lla HELO viesti + portti, johon bindataan. tcp_socket.send("HELO %i\r\n" % bind_port) tcp_data = tcp_socket.recv(1024) udp_port = get_udp(tcp_data) #Luodaan UDP:n headeri osio ja lahetetaan avaava viesti serverille. msg = "The eagle has landed\r\n" eom = False ack = False rem = 0 lenght = len(msg) msg_packet = struct.pack("!??HH64s", eom, ack, lenght, rem, msg) udp_socket.sendto(msg_packet, (host_ip, udp_port)) #Avataan ja puretaan saadut viestit struct.unpack_from toiminnolla #Kaytetaan questions.py tiedoston answers-funktiota oikeiden vastausten toimittamiseen #Lopuksi kun vastausta ei ole, suljetaan yhteys. while (1): data_r, addr = udp_socket.recvfrom(1024) (eom, ack, rem, lenght, msg) = struct.unpack_from("!??HH64s", data_r, 0) #struct.unpack aiheutti virheilmoituksen print msg #Tulostetaan kysymys, jotta voi seurata ohjelman toimintaa message_out = answer(msg) message = struct.pack("!??HH64s", eom, ack, rem, lenght, message_out) udp_socket.sendto(message, (host_ip, udp_port)) print message #Kuten myos vastaus, jolloin tiedetaan, etta ohjelma toimii oikein. if not message_out: break #Suljetaan kumpikin yhteys kun ohjelma on valmis udp_socket.close() tcp_socket.close() print "Closing..."
print count if count > 1: question = question.split('?') answers = "" x = count for n in range(x): _question = question[n] + "?" print "Question" print _question answ = answer(_question) print "\nOur answer:" print answ answers = answers + answ #crypted_answ = encryption.encrypt(answ, key_table[i+1]) #print crypted_answ #data = struct.pack("!??HH64s", False, True, len(answ), 0, crypted_answ) #sUDP.sendto(data, ((host, port))) #print "sent: " + data i = i + 1
EOM = uncoded[0] question = uncoded[4].strip('\x00') if not EOM: if VERBOSE: print "\nQuestion " + str(i + 1) + ", EOM is:", EOM decrypted = encryption.decrypt(question, key_list[i]) print "\nQuestion " + str(i + 1) + " from server" print decrypted answ = answer(decrypted) print "\nOur answer:" print answ crypted_answ = encryption.encrypt(answ, key_table[i + 1]) #print crypted_answ data = struct.pack("!??HH64s", False, True, len(answ), 0, crypted_answ) sUDP.sendto(data, ((host, port))) #print "sent: " + data i = i + 1 else:
def main(): if len(sys.argv) < 3: sys.exit('usage: %s <hostname> <port number>' % sys.argv[0]) try: servAddr= sys.argv[1] servPort= int(sys.argv[2]) except TypeError: sys.exit("port must be an integer") print("STOP!") print("Who would cross the bridge of death must answer me these questions n.") print("Creating TCP socket") TCPs = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print("Finding free port for UDP Socket") portUDP = 10001 while True: try: UDPs = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) UDPs.bind(('', portUDP)) print("UDP socket bound to port: %d" % portUDP) break except OSError: print("Port %d already taken. Trying next port" % portUDP) UDPs.close() portUDP = portUDP + 1 continue print("Trying to form connection to %s at port %d" % (servAddr, servPort)) TCPs.connect((servAddr, servPort)) print("TCP connection formed to address %s at port %d" % (servAddr, servPort)) helo = ("HELO %d MI\r\n" % portUDP) TCPs.send(bytes( helo, "utf-8")) received = TCPs.recvfrom(4096) data = received[0].decode("utf-8") destPort = int(data.split(" ")[1]) destAddr = socket.gethostbyname(servAddr) print("Server address: %s Server UDP port: %d" % (destAddr, destPort)) message = bytes("Ekki-ekki-ekki-ekki-PTANG.", "utf-8") dataOut = struct.pack("!??HH64s", False, True, len(message), 0, message) print("TCP handshake complete. Starting UDP transfer.") UDPs.sendto(dataOut, (servAddr, destPort)) done = False while not done: received = UDPs.recvfrom(1024) dataIn = struct.unpack("!??HH64s", received[0]) senderAddress = received[1] messageLength = len(dataIn[4].decode("utf-8").replace("\x00", "")) if dataIn[2] != messageLength: print( "Message lenght and header length do not match. Sending error message.") message = "Send again." error_message = struct.pack("!??HH64s", False, False, len(message), 0, bytes(message, "utf-8")) UDPs.sendto(error_message, (servAddr, destPort)) continue if messageLength == 0: print( "Empty message received. Sending error message.") message = "Send again." error_message = struct.pack("!??HH64s", False, False, len(message), 0, bytes(message, "utf-8")) UDPs.sendto(error_message, (servAddr, destPort)) continue if senderAddress[0] != destAddr or senderAddress[1] != destPort: print("Sender address does not match destination address. Sending error message.") message = "Send again." error_message = struct.pack("!??HH64s", False, False, len(message), 0, bytes(message, "utf-8")) UDPs.sendto(error_message, (servAddr, destPort)) continue stringList = [] stringList.append(dataIn[4].decode("utf-8")) remaining = dataIn[3] done = dataIn[0] while not (remaining == 0): received = UDPs.recvfrom(1024) dataIn = struct.unpack("!??HH64s", received[0]) stringList.append(dataIn[4].decode("utf-8")) remaining = dataIn[3] done = dataIn[0] #question = dataIn[4].decode("utf-8").strip() question = pieces.parse_message(stringList) print(question) if not done: try: ans = answer(question) print(ans) ansPieces = pieces.pieces(ans) remaining_bytes = len(ansPieces) * 64 except QuestionNotFoundException: print("Question not found. Sending error message.") message = "Send again." error_message = struct.pack("!??HH64s", False, False, len(message), 0, bytes(message, "utf-8")) UDPs.sendto(error_message, (servAddr, destPort)) continue else: for piece in ansPieces: remaining_bytes -= 64 dataOut = struct.pack("!??HH64s", False, True, len(piece), remaining_bytes, bytes(piece, "utf-8")) UDPs.sendto(dataOut, (servAddr, destPort)) UDPs.close() TCPs.close()
if __name__ == "__main__": TCPsocket = socket.socket() UDPsocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) checkarguments() try: UDPsendPort = requestUDPport(TCPsocket) except: sys.exit("Failed to create a connection.") sendinitialmessage(UDPsendPort) # Receive questions and answer them # Exits when message reads "Bye." or when receiving message with EOM as true while True: data, addrWithPort = UDPsocket.recvfrom(1024) address = addrWithPort[0] if address == host: print "HOST:", data eom, ack, length, remaining, msg = struct.unpack("!??HH64s", data) if eom == True: print "Closing UDP socket" UDPsocket.close() break answer = questions.answer(msg) print "CLIENT:", answer sent = struct.pack('!??HH64s', eom, ack, length, remaining, answer) UDPsocket.sendto(sent, (host, UDPsendPort))