class SendingQueue(): ''' Class to sending queue process ''' def __init__(self, server_address): ''' Create SendingQueue object ''' self.threads = [] # gevent provides a synchronized queue (locking is handled) self.queue = queue.Queue() self.socket_mgr = ClientSocket(server_address) def add(self, segments): ''' A list of segments to the sending queue''' for sgmt in segments: self.queue.put(sgmt) def send(self): ''' Iterate continuously looking to send entries in queue ''' logger.debug("Started sending thread") while True: if self.queue.qsize(): self.socket_mgr.send(self.queue.get()) time.sleep(1) # send is non-blocking, don't over send else: time.sleep(3) def start_sending(self, filename, port_list, segments, num_threads): ''' Start a separate thread to begin sending from the send queue. Should be started before breaking up files. As segments are added to queue, it will send, until stop_sending is called. ''' self.add(segments) self.socket_mgr.connect(filename, port_list) for i in range(num_threads): self.threads.append(gevent.spawn(self.send)) return def complete_sending(self): ''' Join all threads created during this send process. This should be done between searching for new files ''' # Wait till rest of send queue is empty # ASSUME no more is being added at this point logger.debug("Waiting for all segments to send before completing send") while self.queue.qsize(): time.sleep(3) # Wait till sending finished while self.socket_mgr.num_currently_sending: logger.debug("Waiting for (%d) segments to finish sending", self.socket_mgr.num_currently_sending) time.sleep(3) # Kill any threads created gevent.killall(self.threads, timeout=5) self.threads = [] self.socket_mgr.disconnect()
class Client(object): def __init__(self): #create login window: self.window = WindowLogin() self.window.on_reset_button_click(self.clear_inputs) self.window.on_login_button_click(self.send_login_data) #self.window.on_window_close(self.exit) #create chat window self.window_chat = WindowChat() #self.window_chat.on_window_close(self.exit) #hide the chat window self.window_chat.withdraw() #####create the client socket self.conn = ClientSocket() self.response_handle_function = {} self.response_handle_function[ RESPONSE_LOGIN_RESULT] = self.response_login_handle self.response_handle_function[ RESPONSE_CHAT] = self.response_chat_handle self.window_chat.on_send_button_click(self.send_chat_data) #define the global variable and record user name self.username = None #flag running program self.isrunning = True def startup(self): # Connect the client socket to the server self.conn.connect() # Since a message may be received at any time, the receiving message should be placed in the thread. # The difference between sever and server is that sever waits for the client response by starting up in a loop. # But each time the loop starts the child thread to see if there are any new user requests that need to be processed. # The client only starts up once (mainloop is an infinite loop). #Then we start the response_handle thread directly, enter the response_handle thread and loop through the child thread t = Thread(target=self.response_handle) t.start() # openning the login window is an endless loop, so finally open it self.window.mainloop() def clear_inputs(self): #clean up the window self.window.clear_username() self.window.clear_password() def send_login_data(self): #send the login message(login number and user name) to the server #get the typed in password username = self.window.get_username() password = self.window.get_password() # generate request text (encapsulation) request_text = RequestProtocol.request_login_result(username, password) #send request text to the server self.conn.send_data(request_text) def response_handle(self): #Continuously receive new messages from the processing server(while true +thread) #while self.isrunning: while True: recv_data = self.conn.recv_data() #parsing message (one dictionary) response_data = self.parse_response_data(recv_data) #handle according to the message handle_function = self.response_handle_function.get( response_data['response_id']) if handle_function: handle_function(response_data) #if response_data['response_id']==RESPONSE_LOGIN_RESULT: #self.response_login_handle(response_data) #elif response_data['response_id']==RESPONSE_CHAT: #self.response_chat_handle(response_data) #no used of self, removed self using static method @staticmethod def parse_response_data(recv_data): #There are two kinds of messages that need to be processed: # 1.Log in response from the server:1001|success|username|user id # or 1001|failure|null # 2.Chat server forwarding response:1002|sender's username|message response_data_list = recv_data.split(DELIMITER) #### response_data = {} response_data['response_id'] = response_data_list[0] if response_data['response_id'] == RESPONSE_LOGIN_RESULT: response_data['result'] = response_data_list[1] response_data['nickname'] = response_data_list[2] response_data['username'] = response_data_list[3] elif response_data['response_id'] == RESPONSE_CHAT: response_data['nickname'] = response_data_list[1] response_data['message'] = response_data_list[2] return response_data def response_login_handle(self, response_data): #login resulr print('Login result recieved') result = response_data['result'] if result == '0': print('Login Failed') #The prompt box displays the title and content showinfo('Login result', 'Login Failed,wrong information!') return showinfo('Login result', 'Login Success!') nickname = response_data['nickname'] self.username = response_data['username'] print('%s has successfully login,nickname is %s' % (self.username, nickname)) #Sets the title of the chat window self.window_chat.set_title(nickname) #Habitually refresh self.window_chat.update() #Display chat window, hide login window self.window_chat.deiconify() self.window.withdraw() def send_chat_data(self): #Gets the contents of the input box and sends it to the server #Get input message = self.window_chat.get_inputs() #clear up input box self.window_chat.clear_input() #Splicing message encapsulation request_text = RequestProtocol.request_chat(self.username, message) #send message self.conn.send_data(request_text) #Show the sending message to the chat area: self.window_chat.append_message('me', message) def response_chat_handle(self, response_data): #Get chat message respond from server sender = response_data['nickname'] message = response_data['message'] self.window_chat.append_message(sender, message) def exit(self): #exit the program self.is_running = False self.conn.close() sys.exit(0)
class Client(object): def __init__(self): #create a window for login self.window = WindowLogin() self.window.on_reset_button_click(self.clear_inputs) self.window.on_login_button_click(self.send_login_data) #self.window.on_window_close(self.exit) #create window for chat self.window_chat = WindowChat() #self.window_chat.on_window_close(self.exit) #hide chat window self.window_chat.withdraw() ###create socket for client self.conn = ClientSocket() self.response_handle_function = {} self.response_handle_function[ RESPONSE_LOGIN_RESULT] = self.response_login_handle self.response_handle_function[ RESPONSE_CHAT] = self.response_chat_handle self.window_chat.on_send_button_click(self.send_chat_data) #define a global variable to recode username online self.username = None #Whether the program is running self.isrunning = True def startup(self): #connect client socket to the server self.conn.connect() #Client may receive message at anytime, so we put this process in a thread #in the server, we use a loop in start up function to wait for the response of client #every loop we create a sub thread to check whether there is new client request #In client we just need to start once, beacuse mainloop is an endless loop #Then we start response_handle, and loop in sub thread t = Thread(target=self.response_handle) t.start() #start login window is a endless loop, we put this at the last of the program self.window.mainloop() def clear_inputs(self): #clear window self.window.clear_username() self.window.clear_password() def send_login_data(self): #send request, username and password to server #get username and password input username = self.window.get_username() password = self.window.get_password() #create a protocol and wrappe it request_text = RequestProtocol.request_login_result(username, password) #send it to server self.conn.send_data(request_text) def response_handle(self): #continually accept data from server #while self.isrunning: while True: recv_data = self.conn.recv_data() #parse data(dictionary) response_data = self.parse_response_data(recv_data) #according to message processing,handle the data handle_function = self.response_handle_function.get( response_data['response_id']) if handle_function: handle_function(response_data) #if response_data['response_id']==RESPONSE_LOGIN_RESULT: #self.response_login_handle(response_data) #elif response_data['response_id']==RESPONSE_CHAT: #self.response_chat_handle(response_data) #self is not used in a static function @staticmethod def parse_response_data(recv_data): #There are two ways to handle messafe #1. server send a login request 1001|success|nickname|username or 1001|fail| #2. server send a chat request 1002|nickname|message response_data_list = recv_data.split(DELIMITER) #### response_data = {} response_data['response_id'] = response_data_list[0] if response_data['response_id'] == RESPONSE_LOGIN_RESULT: response_data['result'] = response_data_list[1] response_data['nickname'] = response_data_list[2] response_data['username'] = response_data_list[3] elif response_data['response_id'] == RESPONSE_CHAT: response_data['nickname'] = response_data_list[1] response_data['message'] = response_data_list[2] return response_data def response_login_handle(self, response_data): #response login print('Login result recieved') result = response_data['result'] if result == '0': print('Login Failed') #print the title and content showinfo('Login result', 'Login Failed,wrong information!') return showinfo('Login result', 'Login Success!') nickname = response_data['nickname'] self.username = response_data['username'] print('%s has successfully login,nickname is %s' % (self.username, nickname)) #set title of chat window self.window_chat.set_title(nickname) #refersh self.window_chat.update() #show the chat window and hide login window self.window_chat.deiconify() self.window.withdraw() def send_chat_data(self): #get message in the input box and send it to the server #get message message = self.window_chat.get_inputs() #clear the input box self.window_chat.clear_input() #join message together and wrappe it request_text = RequestProtocol.request_chat(self.username, message) #send the message self.conn.send_data(request_text) #show the message client send in chat window self.window_chat.append_message('me', message) def response_chat_handle(self, response_data): #receive the chat response by server sender = response_data['nickname'] message = response_data['message'] self.window_chat.append_message(sender, message) def exit(self): #exit program self.is_running = False self.conn.close() sys.exit(0)