我正在使用asyncore来实现发布订阅.我理解使用twisted或ZMQ可能是一个更好的解决方案,但在这种情况下它需要是纯python.等待连接时,CPU使用率约为1%,一旦客户端连接CPU使用率跳转写入高达100%.即使客户端断开连接,它也不会降回.
我的服务器类:
class Host(asyncore.dispatcher):
log = logging.getLogger('Host')
def __init__(self, port=7655):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind(('0.0.0.0', port,))
self.listen(5)
self.clients = []
def handle_accept(self):
socket, addr = self.accept()
self.log.info("Aceepted client at {0}:{1}".format(addr[0], addr[1]))
self.clients.append(RemoteClient(self, socket, addr))
def broadcast(self, message):
self.log.info("Broadcasting message: {0}".format(message))
for client in self.clients:
client.message(message)
Run Code Online (Sandbox Code Playgroud)
我的经纪人:
class RemoteClient(asyncore.dispatcher):
log = logging.getLogger('Host')
def __init__(self, host, socket, address):
asyncore.dispatcher.__init__(self, socket)
self.host = host
self.outbox = collections.deque()
def message(self, message):
self.outbox.append(message)
def handle_write(self):
if not self.outbox:
return
message = self.outbox.popleft()
if len(message) > …Run Code Online (Sandbox Code Playgroud) 我尝试用asyncore做简单的异步http客户端:这段代码工作正常,输出是(快速执行):
www.gmail.com : recv http code: 301
www.yandex.ru : recv http code: 200
www.python.org : recv http code: 200
www.google.ru : recv http code: 200
www.gravatar.com : recv http code: 302
www.com.com : recv http code: 302
www.yahoo.com : recv http code: 302
www.bom.com : recv http code: 301
Run Code Online (Sandbox Code Playgroud)
但是,与我不存在主机的取消注释:
#c = AsyncHTTP('http://www.no-such-host.ru') #!this line breaks execution!
Run Code Online (Sandbox Code Playgroud)
执行中断,代码挂起一段时间,输出部分数据并挂起,没有最后的数据输出:
connection error: [Errno -5] No address associated with hostname
www.gmail.com : recv http code: 301
www.yandex.ru : recv http code: 200
www.yahoo.com …Run Code Online (Sandbox Code Playgroud) 我在使用带有AF_UNIX套接字的asyncore时遇到了一些问题.这段代码
import asyncore, socket, os
class testselect(asyncore.dispatcher):
path = '/tmp/mysocket'
def __init__(self):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_UNIX, socket.SOCK_DGRAM)
self.bind(self.path)
self.buffer = 'buffer'
def handle_connect(self):
print 'handle_connect'
pass
def handle_close(self):
print 'handle_close'
if os.path.exists(self.path)
os.remove(self.path)
self.close()
def handle_read(self):
print 'handle_read'
print self.recv(8192)
def writable(self):
print 'writable'
return (len(self.buffer) > 0)
def handle_write(self):
print 'handle_write'
sent = self.send(self.buffer)
self.buffer = self.buffer[sent:]
client = testselect()
asyncore.loop()
Run Code Online (Sandbox Code Playgroud)
如果我执行代码
$ python select_prova.py
writable
handle_connect
handle_write
handle_close
$
Run Code Online (Sandbox Code Playgroud)
它立即退出,不等待读写.如果我改变代码以强制writable()方法总是返回False,它正确地等待输入,我可以像这样与socat通信
$ socat readline UNIX:/tmp/mysocket
Run Code Online (Sandbox Code Playgroud)
但只是为了阅读(逻辑上写不起作用,因为writable()返回False).我的代码中是否有错误,或者我无法使用asyncore/select()管理AF_UNIX套接字?
有两个文件:server.py和client.py,都是在asyncore.dispatcher的帮助下编写的
Server.py
import asyncore, socket
class Server(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.bind(('', port))
self.listen(1)
print "Waiting for connection..."
def handle_accept(self):
socket, address = self.accept()
print 'Connection by', address
socket.send("Hello Server")
def handle_read(self):
print "Reading..."
out_buffer = self.recv(1024)
if not out_buffer:
self.close()
print out_buffer
def handle_closed(self):
print "Server: Connection Closed"
self.close()
s = Server('0.0.0.0', 5007)
asyncore.loop()
Run Code Online (Sandbox Code Playgroud)
Client.py
import asyncore, socket
class Client(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((host, port))
print "Client Start..."
def handle_close(self):
print "Client: …Run Code Online (Sandbox Code Playgroud) 我想为某个项目构建一个自定义服务器,但我不知道和服务器之间有什么区别,什么更好用,以及为什么asyncoreasyncio
我正在编写一个简单的套接字服务器,我想跟踪客户端状态(身份验证和其他内容)。每次调用 handle_read() 时,我对该特定客户端一无所知。如果我知道客户的 ID 或其他东西,那会有所帮助。这是我到目前为止所拥有的:
import asyncore
import socket
class EchoHandler(asyncore.dispatcher_with_send):
def handle_read(self):
data = self.recv(8192)
self.send(data)
class EchoServer(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((host, port))
self.listen(5)
def handle_accept(self):
pair = self.accept()
if pair is None:
pass
else:
sock, addr = pair
print 'Incoming connection from %s' % repr(addr)
handler = EchoHandler(sock)
server = EchoServer('localhost', 8080)
asyncore.loop()
Run Code Online (Sandbox Code Playgroud) 我是Python的新手(虽然我已经用Java编程多年了),我正在开发一个简单的基于套接字的网络应用程序(只是为了好玩).我的想法是我的代码连接到远程TCP端点,然后侦听从服务器推送到客户端的任何数据,并对此执行一些解析.
从服务器 - >客户端推送的数据是UTF-8编码文本,每行由CRLF(\x0D\x0A)分隔.您可能已经猜到:想法是客户端连接到服务器(直到被用户取消),然后在它们进入时读取和解析这些行.
我已经设法让这个工作,但是,我不确定我这样做是否正确.因此,我的实际问题(代码要遵循):
asyncore?目前,数据正在被读取和缓冲,如下所示:
def handle_read(self):
self.ibuffer = b""
while True:
self.ibuffer += self.recv(self.buffer_size)
if ByteUtils.ends_with_crlf(self.ibuffer):
self.logger.debug("Got full line including CRLF")
break
else:
self.logger.debug("Buffer not full yet (%s)", self.ibuffer)
self.logger.debug("Filled up the buffer with line")
print(str(self.ibuffer, encoding="UTF-8"))
Run Code Online (Sandbox Code Playgroud)
该ByteUtils.ends_with_crlf函数只是检查缓冲区的最后两个字节\x0D\x0A.第一个问题是主要问题(答案是基于此),但任何其他想法/提示都表示赞赏.谢谢.
我必须将数据仅发送到连接,我可以这样做吗?
服务器:
import asyncore, socket, threading
class EchoHandler(asyncore.dispatcher_with_send):
def __init__(self,sock):
asyncore.dispatcher.__init__(self,sock=sock);
self.out_buffer = ''
def handle_read(self):
datos = self.recv(1024);
if datos:
print(datos);
self.sock[0].send("signal");
class Server(asyncore.dispatcher):
def __init__(self,host='',port=6666):
asyncore.dispatcher.__init__(self);
self.create_socket(socket.AF_INET, socket.SOCK_STREAM);
self.set_reuse_addr();
self.bind((host,port));
self.listen(1);
def handle_accept(self):
self.sock,self.addr = self.accept();
if self.addr:
print self.addr[0];
handler = EchoHandler(self.sock);
def handle_close(self):
self.close();
cliente = Server();
asyncore.loop()
Run Code Online (Sandbox Code Playgroud)
这一行是一个例子失败,但我想将数据发送到零袜子:
self.sock[0].send("probando");
Run Code Online (Sandbox Code Playgroud)
例如,如果我有5个套接字,请选择发送数据的人