2016-06-03 2 views
2

Вот простой клиент, который подключается и отправляет текстовое сообщение:Python асинхронного гнездо RECV не работает

class Client(asyncore.dispatcher): 

    def __init__(self, host, port): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket() 
     self.connect((host, port)) 
     self.buffer = bytes("hello world", 'ascii') 

    def handle_connect(self): 
     pass 

    def handle_close(self): 
     self.close() 

    def handle_read(self): 
     print(self.recv(8192)) 

    def writable(self): 
     return (len(self.buffer) > 0) 

    def writable(self): 
     return True 

    def handle_write(self): 
     sent = self.send(self.buffer) 
     print('Sent:', sent) 
     self.buffer = self.buffer[sent:] 


client = Client('localhost', 8080) 
asyncore.loop() 

А вот сервер, который должен получить сообщение и эхо его обратно:

class Server(asyncore.dispatcher): 
    def __init__(self, host, port): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket() 
     self.set_reuse_addr() 
     self.bind((host, port)) 
     self.listen(5) 

    def handle_read(self): 
     self.buffer = self.recv(4096) 
     while True: 
      partial = self.recv(4096) 
      print('Partial', partial) 
      if not partial: 
       break 
      self.buffer += partial 

    def readable(self): 
     return True 

    def handle_write(self): 
     pass 

    def handle_accepted(self, sock, addr): 
     print('Incoming connection from %s' % repr(addr)) 
     self.handle_read() 
     print(self.buffer) 


if __name__ == "__main__": 
    server = Server("localhost", 8080) 
    asyncore.loop() 

Проблема в том, что сервер ничего не читает. При печати self.buffer на выходе:

б ''

Что я делаю неправильно?

+0

Где находится 'self.accept()' в коде вашего сервера? – qvpham

+0

Я думаю, что это не требуется в асинхронных сокетах: https://docs.python.org/3/library/asyncore.html У меня этот код из последнего примера. А также соединение принимается, поскольку оператор print в handle_accepted распечатывает его. – conquester

+0

ОК, я видел его. Я прочитал документ Py 2. Но он думает, что вы должны использовать отдельный класс для связи с клиентом. Если вы пишете все вместе, это не может быть асинхронным. – qvpham

ответ

1

Прежде всего, вам нужны два обработчика: один для серверного сокета (где вы ожидаете только accept) и один для фактических коммуникационных сокетов. Кроме того, вы можете звонить только read один раз в handle_read; если вы вызываете его дважды, второй вызов может блокироваться, и это запрещено в асинхронном программировании. Не волнуйся; если ваше чтение не получило все, вы сразу же получите уведомление, как только ваш обработчик будет возвращен.

import asyncore 

class Handler(asyncore.dispatcher): 
    def __init__(self, sock): 
     self.buffer = b'' 
     super().__init__(sock) 

    def handle_read(self): 
     self.buffer += self.recv(4096) 
     print('current buffer: %r' % self.buffer) 


class Server(asyncore.dispatcher): 
    def __init__(self, host, port): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket() 
     self.set_reuse_addr() 
     self.bind((host, port)) 
     self.listen(5) 

    def handle_accepted(self, sock, addr): 
     print('Incoming connection from %s' % repr(addr)) 
     Handler(sock) 


if __name__ == "__main__": 
    server = Server("localhost", 1234) 
    asyncore.loop() 
Смежные вопросы