推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
sbmzhcn
V2EX  ›  Python

gevent + TCPServer(StreamServer) 当客户端长久不发信息时,如何自动断开当前连接

  •  
  •   sbmzhcn · Mar 21, 2015 · 5879 views
    This topic created in 4070 days ago, the information mentioned may be changed or developed.
    TCPServer 如何处理客户端连接之后不发信息,然后服务器端自动给他断开呢?有没有这方面的例子,谢谢。
    13 replies    2015-03-24 22:11:09 +08:00
    cheng007
        1
    cheng007  
       Mar 21, 2015   ❤️ 1
    bSendData = False

    def check(fd):
    while True:
    gevent.sleep(30)
    #check socket
    if bSendData:
    bSendData = false
    else:
    # close socket fd
    fd.close()

    def recv(fd):
    while True:
    data = fd.recv(100)
    if len(data) <= 0:
    return
    else:
    bSendData = True

    gevent.spawn(recv, fd)
    gevent.spawn(check,fd)
    你可以为每条连接创建一个协程定时检查,这段时间客户端没有发数据。
    大致如此,就是消耗有点大,需要多创建一个协程了
    cheng007
        2
    cheng007  
       Mar 21, 2015
    代码没办法格式化,你凑合看看就好
    155
        3
    155  
       Mar 21, 2015
    recv数据和心跳包套在with gevent.Timeout里.
    wyxfcy
        4
    wyxfcy  
       Mar 21, 2015
    @155 正解。 gevent里面, socket自身的timeout无效。
    fordoo
        5
    fordoo  
       Mar 21, 2015
    x14oL
        6
    x14oL  
       Mar 22, 2015   ❤️ 1
    @cheng007 可以理解成gevent模块是真并发吗?
    yueyoum
        7
    yueyoum  
       Mar 22, 2015
    erlang 大法好
    cloudzhou
        8
    cloudzhou  
       Mar 23, 2015
    @yueyoum 这种模型和语言无关的,和设计有关。
    @fordoo keep-alive选项是很好的选择,但是keep-alive是协议里面支持的,为的是保证链接可用,而不是问题里面提到的:长久不发信息,就断掉链接。

    比较环保的一种做法是:
    维护一个 lru cache, connection 就是 key。
    当每个链接接受到新的数据之后,更新 connection 当前时间,lru 更新。
    当 lur 超过一定长度,从某个时间段之后,强制断掉之后的 connection。

    可以使用 redis 来做这件事情,File descriptor 作为 key, 但是需要保持 File descriptor -> connection 的映射。
    yueyoum
        9
    yueyoum  
       Mar 23, 2015
    @cloudzhou
    我没说 和语言 有关, 只是在erlang里要实现这样的功能,很容易。
    如果LZ用erlang来实现, 就不会发这样的帖子来问问题了
    cheng007
        10
    cheng007  
       Mar 23, 2015   ❤️ 1
    @x14oL 我对gevent的api不够熟悉,@155的写法是正确的。
    你可以去了解一下libevent, 还有node.js的底层库libuv,gevent并不是真正的并发,他只是利用greenlet协程封装了异步过程。
    cheng007
        11
    cheng007  
       Mar 23, 2015
    @yueyoum 我也很喜欢erlang,非常欣赏erlang的理念。
    fordoo
        12
    fordoo  
       Mar 23, 2015
    @cloudzhou 审题错误,感谢提醒。
    sbmzhcn
        13
    sbmzhcn  
    OP
       Mar 24, 2015
    感谢回复,我用的python写的一个比较简单的程序。我是希望在python代码上作一个修改就可以搞定的。
    @cloudzhou 这个做法应该是可以尝试的。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3901 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 45ms · UTC 04:40 · PVG 12:40 · LAX 21:40 · JFK 00:40
    ♥ Do have faith in what you're doing.