Asyncore loop and raw_input problem

I am trying to learn an asynchronous module. So I decided to develop a chat program. I have to listen to the network and broadcast the udp packets at the same time. But the problem is that the user enters a message, the user cannot see other messages sent by other users. What should I do? My code is:

#!/usr/bin/python # -*- coding: utf-8 -*- import asyncore import socket class Listener(asyncore.dispatcher): def __init__(self, port): asyncore.dispatcher.__init__(self) self.port = port self.create_socket(socket.AF_INET, socket.SOCK_DGRAM) self.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.bind(('', self.port)) def handle_connect(self): print "CONNECTED." def handle_read(self): data, addr = self.recvfrom(1024) print str(addr) + " > " + data def handle_write(self): pass class Sender(asyncore.dispatcher): def __init__(self, port): asyncore.dispatcher.__init__(self) self.buffer = "" self.port = port self.create_socket(socket.AF_INET, socket.SOCK_DGRAM) self.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) self.bind(('',0)) def handle_connect(self): print "CONNECTED." def handle_read(self): pass def handle_write(self): if self.buffer != "": sent = self.sendto(self.buffer, ('<broadcast>', self.port)) self.buffer = self.buffer[sent:] def handle_close(self): self.close() def serve_forever(self): asyncore.loop(count = 10) if __name__ == "__main__": Listener(50000) sender = Sender(50000) while True: sender.serve_forever() sender.buffer += raw_input("Message:") 
+7
source share
2 answers

The call to raw_input blocked, but you can also use asyncore. You need to add a third player, for example:

 class CmdlineClient(asyncore.file_dispatcher): def __init__(self, sender, file): asyncore.file_dispatcher.__init__(self, file) self.sender = sender def handle_read(self): self.sender.buffer += self.recv(1024) import sys sender = Sender(50000) cmdline = CmdlineClient(sender, sys.stdin) 
+9
source
 #!/usr/bin/env python # -*- coding: utf8 -*- import asyncore import logging import sys logging.basicConfig(level=logging.DEBUG, format='[*] %(name)s - %(funcName)16s - %(message)s') class ConsoleHandler(asyncore.file_dispatcher): """Enable console interactive for socket read/write. """ def __init__(self, sender, file): asyncore.file_dispatcher.__init__(self, file) self.current_chat = sender self.BUFSIZE = 1024 def handle_read(self): self.current_chat.out_buffer += self.recv(self.BUFSIZE) class ChatManager(asyncore.dispatcher): """Handle tcp in-connections, ex: send commands to targets. """ def __init__(self, _sock=None, _map=None): self.logger = logging.getLogger('ChatManager') self.BUFSIZE = 1024 asyncore.dispatcher.__init__(self, _sock, _map) self.out_buffer = '' def handle_read(self): """Called when the asynchronous loop detects that a read() call on the channel socket will succeed.""" data = self.recv(self.BUFSIZE) self.logger.debug('%d bytes | client <- server' % len(data)) print(data.strip()) # self.send(data) self.logger.debug('%d bytes | client -> server' % len(data)) def handle_write(self): """Called when the asynchronous loop detects that a writable socket can be written. Often this method will implement the necessary buffering for performance. For example: """ if self.out_buffer != "": sent = self.send(self.out_buffer) self.out_buffer = self.out_buffer[sent:] def handle_error(self): """Called when an exception is raised and not otherwise handled. The default version prints a condensed traceback. """ self.logger.debug('socket exception') def handle_close(self): """Called when the socket is closed. """ self.close() class Listener(asyncore.dispatcher): """Start a tcp listener (default: 127.0.0.1:4444), and wait for connections. If a new connection, `ChatManager' will try to handle it. """ def __init__(self, addr=('127.0.0.1', 4444), max_connections=4): self.logger = logging.getLogger('Listener') asyncore.dispatcher.__init__(self) self.logger.debug('create a socket') self.create_socket(asyncore.socket.AF_INET, asyncore.socket.SOCK_STREAM) # socket reuse address self.set_reuse_addr() self.bind(addr) self.logger.debug('bind socket address') self.listen(max_connections) self.logger.debug('listen socket on %s:%s' % addr) def handle_accept(self): client, caddr = self.accept() self.logger.debug('client: %s:%s' % caddr) self.logger.debug('Enter into ChatManager') ConsoleHandler(ChatManager(client), sys.stdin) if __name__ == "__main__": Listener() asyncore.loop() 

Please note the following usage:

  $ python ChatManager.py [*] Listener - __init__ - create a socket [*] Listener - __init__ - bind socket address [*] Listener - __init__ - listen socket on 127.0.0.1:4444 

Please make a connection to the char server with:

 $ nc -v 127.0.0.1 4444 

Then you can communicate with the server on the terminal.

0
source

All Articles