设为首页 收藏本站
查看: 752|回复: 0

[经验分享] python 土拿渡 socket

[复制链接]

尚未签到

发表于 2017-4-29 07:33:11 | 显示全部楼层 |阅读模式
下面和大家分享一下tornado 如何实现异步处理
下面的程序只能支持多线程的异步处理方式,扩展性一般,如果,可以改进为进程的方式扩展性会好很多 :)
之所以使用tornado 是因为,tornado 性能比较乐观,
具体比较请看下面的文章:http://programmingzen.com/2009/09/13/benchmarking-tornado-vs-twisted-web-vs-tornado-on-twisted/
Client 端代码
>>> import socket
>>> d = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> d.connect((HOST,PORT))


Server 端代码,需要Linux 服务器
#encoding = utf-8
import errno
import functools
import socket
import time
import os
import traceback
import memcache
from tornado import ioloop, iostream
from threading import Thread
from Queue import Queue
from config import *
streamDict = {}
streamRequests = {}
################################# Utils ###############################
def stream_add(stream,count):
"""
添加 Stream
"""
streamkey = str(stream)
streamDict[streamkey] = (stream,0)
streamRequests[streamkey] = Queue()
def stream_remove(streamkey,stream):
"""
删除 Stream
"""
try:
stream.close()
except:
pass
del streamDict[streamkey]
del streamRequests[streamkey]
################################# Response ###############################
class ClockResponse(Thread):
"""
定时处理请求接口
"""
def __init__ (self):
"""
初始化
"""
Thread.__init__(self)
self.flag = True
self.count = 0
def run(self):
"""
运行线程
"""
while self.flag:
#打印 LOG,N次/打印
ct = self.count % 10
if ct == 0:
print 'now connections:%s'%(len(streamDict))
self.count = ct + 1
#循环处理请求
for streamkey,(stream,num) in streamDict.items():
try:
#这里返回Response
queue = streamRequests[streamkey]
print "queue.get()",queue.get()
print "q.qsize()",queue.qsize()
stream.write('haha')
except:
streamDict[streamkey] = (stream,num+1)
#去死吧.......
if num>DEAD_VALUE:
stream_remove(streamkey,stream)
time.sleep(SLEEP_TIME)
def stop(self):
self.flag = False
################################# Request ###############################
class SocketRequest(object):
"""
Socket 请求
"""
def __init__(self, stream, address):
self.stream = stream
self.streamkey = str(stream)
self.address = address
#开始读取数据
self.stream.read_until("\r\n", self.on_request)
def on_request(self,data):
"""
接收处理请求
"""
#将数据加载到 Queue
print "on_request" , data
queue = streamRequests[self.streamkey]
queue.put(data)
#继续读取请求
self.stream.read_until("\r\n", self.on_request)

def connection_ready(sock, fd, events):
"""
启动 Connection 监听,处理程序
"""
while True:
try:
connection, address = sock.accept()
except socket.error, e:
if e[0] not in (errno.EWOULDBLOCK, errno.EAGAIN):
raise
return
#non-block
connection.setblocking(0)
stream = iostream.IOStream(connection)
#保存stream
stream_add(stream,0)
#接收Socket 请求
SocketRequest(stream,address)

if __name__ == '__main__':
#pidfile = open(os.path.join(settings.PROJECT_PATH,'tornadoServer.pid'),'w')
#pidfile.write(str(os.getpid()))
#pidfile.close()
#接收请求
clock = ClockResponse()
clock.start()
#定义Socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) #这里的0 dummy protocol for TCP
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setblocking(0)
sock.bind(("", SERVER_PORT))
sock.listen(9999)
#获得ioloop
io_loop = ioloop.IOLoop.instance()
callback = functools.partial(connection_ready, sock)
io_loop.add_handler(sock.fileno(), callback, io_loop.READ)
#启动服务
try:
io_loop.start()
except KeyboardInterrupt:
io_loop.stop()
clock.stop()
print "exited cleanly"



TCP/IP module for linux 2.6 dummy版
1、概述
    英文单词dummy是虚假的意思,dummy版的TCP/IP module就是实现一个虚假的传输层协议,该协议不能完成任何实际的网络通讯。它通过module自身提供的一个经过改造的环回网络设备驱动程序mylo,展示网络数据在TCP/IP协议栈中发送和接收的整个流程。其意义在于为后续的实际的STREAM, DGRAM, RAW的开发提供一个基本的程序框架,以及初步验证这个框架的可行性,同时也帮助更好的理解2.6内核中整个TCP/IP协议栈的实现原理。

2、编译与安装
    dummy版的module与第一版相比较,在模块划分和Makefile上作了很多改进。当前初步按TCP/IP协议栈的层次结构分为五个模块,下面是整个源代码目录树的基本情况:
    ipv4                      顶层目录。
     |
     |--inet                    inet域,主要完成inet域最顶层的一些基本操作。
     |
     |--application         应用层,现在主要为一个dummy协议的测试应用程序。
     |
     |--transport           传输层,目前只有一个dummy协议。
     |
     |--network             网络层。
     |
     |--datalink              数据链路层,目前只实现了环回网络设备驱动程序mylo。
     |
     |--core                  核心模块,连接数据链路层和网络层,传递它们之间的数据。
     |
     |--include              头文件
     |
     |--load.sh unload.sh     装载和卸载脚本
     |
     |--Makfile env.mk          makefile文件。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-370562-1-1.html 上篇帖子: Python 正则表达式二 下篇帖子: python模块学习 ---- Cookie
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表