- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在 python 上使用 asyncore 获得了 tcp 服务器:
class AsyncClientHandler(asyncore.dispatcher_with_send):
def __init__(self,sock):
asyncore.dispatcher_with_send.__init__(self,sock)
self.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
self.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
self.message=""
self.protocol=Protocol(DBSession, logger)
def handle_read(self):
data = self.recv(8192)
if data:
self.message+=data
while TERMINATOR in self.message:
index=self.message.index(TERMINATOR)
msg=self.message[:index]
self.message=self.message[index+len(TERMINATOR):]
answer=self.protocol.process_msg(msg, DBSession, tarif_dict)
if answer:
msg = HEADER+answer+TERMINATOR
self.send(msg)
def handle_close(self):
self.close()
class AsyncServer(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
self.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
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
logging.info("Incoming connection from %s",repr(addr))
AsyncClientHandler(sock)
有些客户端并没有关闭连接,所以在某些时候服务器会因为大量的套接字而崩溃。
如何在一段时间后关闭不活动的套接字? settimeout 不起作用。
最佳答案
要实现这一点,您可以使用 TCP 的 Keepalive(就像您已经做过的那样)并设置其延迟、ping...但是这个方法应该只用于持久连接并且只在 Unix 上可用。读一读 here .
您还可以对套接字进行一些调度,在一段时间后关闭它们,或者在它们处于事件状态时延迟它们。我用你的代码做了一个例子:
import sched, time
class SocketSched(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.daemon = True
self.to_run = []
self.scheds = {}
self.start()
def add(self, what):
self.to_run.append(what.values()[0])
self.scheds.update(what)
def run(self):
while True:
if self.to_run:
run = self.to_run.pop()
if not run.empty(): run.run()
else: self.to_run.append(run)
这里我们在不同的线程中定义了新的调度器类——这很重要,sched
模块会不断地阻塞,比如 asyncore.loop()
。这需要稍微修改您的代码:
class AsyncClientHandler(asyncore.dispatcher_with_send):
def __init__(self,sock, sch_class):
...
self.delay = 10
self.sch_class = sch_class
self.sch = sched.scheduler(time.time, time.sleep)
self.sch_class.add({self.fileno(): self.sch})
self.event = self.sch_class.scheds[self.fileno()].enter(self.delay, 1, self.handle_close, ())
...
def delay_close(self):
self.sch_class.scheds[self.fileno()].cancel(self.event)
self.event = self.sch_class.scheds[self.fileno()].enter(self.delay, 1, self.handle_close, ())
...
def handle_close(self):
try:
self.sch_class.scheds[self.fileno()].cancel(self.event)
except:
pass
...
self.delay
是以秒为单位的超时。这段时间过去后,没有任何 Action 延迟它,套接字将关闭。 handle_close() 中的一行确保它不会由于调度程序中的任务而被调用两次。
现在您必须将 self.delay_close()
添加到确保套接字处于事件状态的每个方法的开头,例如。 handle_read()
.
服务器类(获取 SocketSched 实例并将其传递给新 channel ):
class AsyncServer(asyncore.dispatcher):
def __init__(self, host, port, sch_class):
...
self.sch_class = sch_class
...
def handle_accept(self):
...
AsyncClientHandler(sock, self.sch_class)
准备好了。使用这个:
server = AsyncServer('', 1337, SocketSched())
asyncore.loop()
此解决方案有效,但在某些关闭事件上可能容易出错。无论如何,套接字将在给定超时发生时读取、延迟和关闭。不幸的是,运行这样的调度循环会占用一些 CPU。
关于python - asyncore 关闭旧套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17300317/
我已经编写(大部分是复制的)一个非常简单的 python 脚本来充当 xbmc 的来电显示插件。除了关闭套接字外,它按预期工作。我已经确认 xbmc.abortRequested(XBMC 正在关闭的
我正在编写一个简单的套接字服务器,我想跟踪客户端状态(身份验证等)。每次调用 handle_read() 时,我对那个特定的客户端一无所知。如果我知道客户的 ID 之类的东西会有所帮助。这是我到目前为
我编写了一个程序,可以使用 asyncore 模块同时与许多服务器进行通信。在大多数情况下,我只是响应从服务器接收的数据,但有时我需要发送一些“不同步”的数据。默认超时为 30 秒,在发送数据包之前有
我在 python 上使用 asyncore 获得了 tcp 服务器: class AsyncClientHandler(asyncore.dispatcher_with_send): def
对于初学者,我使用了 Twisted 和 SocketServer 以及 ForkMixIn、ThreadMixIn 并尝试了“线程池”recepies。 但是,我想在 Python 中做一些特别的工
我在 python 中实现了一个基于 asyncore 的 IRC 机器人,但我无法捕获在 asyncore 分派(dispatch)类的方法中发生的异常。这是我的最小示例: #!/usr/bin/e
我开始学习这个 asyncore.dispatcher 模块,当我运行第一个示例程序时,它给出了如下错误: Python 版本 2.6 asyncore 模块已安装,其中也有调度程序类。可能是什么问题
我使用 python asyncore 编写了一个异步客户端,遇到了一些问题。我已经在这个帮助下解决了这个问题: Asyncore client in thread makes the whole p
我是 Python 的新手(尽管我已经使用 Java 编程多年),并且我正在开发一个简单的基于套接字的网络应用程序(只是为了好玩)。我的想法是,我的代码连接到一个远程 TCP 端点,然后监听从服务器推
我需要连接到服务器(例如 smpp 服务器)并每 2 秒发送一次周期性数据,代码如下: import asyncore, socket, threading, time class SClient(a
看来我可以通过两种方式用 python 做快速爬虫: 带 block 套接字的线程池 非阻塞套接字选择、asyncore 等。 我认为这里没有真正需要线程的地方,解决方案 #2 更好。 哪个更好,为什
我尝试使用 asyncore 做简单的异步 http 客户端:这段代码工作正常,输出是(足够快): www.gmail.com : recv http code: 301 www.yandex.
我想异步阅读网站,据我所知,urllib 无法做到这一点。现在我尝试使用普通套接字进行阅读,但 HTTP 让我很痛苦。我遇到了各种时髦的编码,例如 transfer-encoding: chunked
我不熟悉 asyncore ,并且除了一些扭曲教程的介绍外,对异步编程的了解非常有限。 我最熟悉线程并在我所有的应用程序中使用它们。一个特定的应用程序使用 couchdb数据库作为其接口(interf
在 pyQt 中是否有等同于 asyncore/asynchat 的东西? 如果没有,那么我相信在客户端-服务器 GUI 应用程序中使用 asyncore/asynchat 不会有问题,对吧? 最佳答
“该模块为编写异步套接字服务客户端和服务器提供了基本的基础设施。” http://docs.python.org/2/library/asyncore.html#module-asyncore 如果我
我想使用 SocketServer 模块为服务器的请求处理程序中的各个连接添加超时。 首先让我说这是我第一次尝试使用 Python 进行网络编程。我已经对 SocketServer.BaseReque
我使用 asyncore 使用“length:message”类型的协议(protocol)与远程服务器进行通信。有人可以推荐我一种从套接字读取确切字节数的方法吗?我试图使用handle_read来填
我正在构建一个小型 MMORPG,我尝试使用异步而不是线程。 1) 我如何将数据发送到某些客户端,因为在线程中,a 保存了每个客户端套接字并以字典 a 的当前方式保存其唯一的 id 作为键。那么我怎么
嗨,我是 Python 编程新手。我可以知道为什么我的服务器没有收到客户端发送的消息吗?我试图将数据从客户端发送到服务器并使服务器将其显示在控制台中... 客户端.py import asyncore
我是一名优秀的程序员,十分优秀!