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

[经验分享] Python Twisted 框架中 socket通信

[复制链接]

尚未签到

发表于 2015-4-23 05:27:10 | 显示全部楼层 |阅读模式
  转载:http://blog.iyunv.com/jackyyen/archive/2009/04/13/4069887.aspx
  // 部分一
  Twisted使用了更多的基于事件的方式。要写一个基本的服务器,你要实现事件处理器,它处理诸如一个新的客户端连接、新的数据到达和客户端连接中断等情况。在Twisted中,你的事件处理器定义在一个protocol中;你也需要一个factory,当一个新的连接到达时它能够构造这个protocol对象,但是如果你仅仅想创建一个自定义的Protocol类的实例的话,你可以使用来自Twisted的factory,Factory类在模块twisted.internet.protocol中。当你写你的protocol时,使用twisted.internet.protocol模块中的Protocol作为你的父类。当你得到一个连接时,事件处理器 connectionMade被调用;当你丢失了一个连接时,connectionLost被调用。从客户端接受数据使用处理器 dataReceived。但是你不能使用事件处理策略向客户端发送数据;要向客户端发送数据,你可以使用self.transport,它有一个 write方法。它也有一个client属性,其中包含了客户端的地址(主机名和端口)。

  
  下面这个例子是一个Twisted版的服务器。其中实例化了Factory并设置了它的protocol属性以便它知道使用哪个protocol与客户端通信(这就是所谓的你的自定义 protocol)。然后你使用factory开始监听指定的端口,factory通过实例化的protocol对象处理连接。监听使用reactor模块中的listenTCP函数。最后,你通过调用reactor模块中的run函数来开始服务器。
  


DSC0000.gif DSC0001.gif 代码



from twisted.internet import reactor
from twisted.internet.protocol import Protocol, Factory
# 定义你Protocol类
class SimpleLogger(Protocol):
    def connectionMade(self):
        print 'Got connection from', self.transport.client
    def connectionLost(self, reason):
        print self.transport.client, 'disconnected'
    def dataReceived(self, data):
        print data

# 实例化Factory

factory = Factory()
# 设置factory的protocol属性以便它知道使用哪个protocol与客户端通信(这就是所谓的你的自定义
# protocol)

factory.protocol = SimpleLogger
# 监听指定的端口

reactor.listenTCP(1234, factory)
# 开始运行主程序
reactor.run()

  
为你的处理目的而写一个自定义的protocol是很容易的。模块twisted.protocols.basic中包含了几个有用的已存在的 protocol,其中的LineReceiver执行dataReceived并在接受到了一个完整的行时调用事件处理器lineReceived。如果当你在接受数据时除了使用lineReceived,还要做些别的,那么你可以使用LineReceiver定义的名为rawDataReceived 事件处理器。下面是一使用LineReceiver的服务器例子:
  


代码



from twisted.internet import reactor
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
class SimpleLogger(LineReceiver):
    def connectionMade(self):
        print 'Got connection from', self.transport.client
    def connectionLost(self, reason):
        print self.transport.client, 'disconnected'
    def lineReceived(self, line):
        print line
factory = Factory()
factory.protocol = SimpleLogger
reactor.listenTCP(1234, factory)
reactor.run()
  
  //部分二: 一个server实例
  


代码



   # -*- coding: UTF-8 -*-   
  #Twisted MMORPG   
  from twisted.internet.protocol import Factory   
  from twisted.protocols.basic import LineOnlyReceiver   
  from twisted.internet import reactor   
  import random   
  import string   
  class Game(LineOnlyReceiver):      
     def lineReceived(self, data):     
         self.factory.sendAll("%s" % (data))   
     def getId(self):           
         return str(self.transport.getPeer())   
     def connectionMade(self):           
         print "New User Login:", self.getId()     
         self.transport.write("欢迎来到MMO世界!\n")           
         self.factory.addClient(self)      
     def connectionLost(self, reason):           
         self.factory.delClient(self)   
class GameFactory(Factory):      
     protocol = Game      
     def __init__(self):           
         self.clients = []   
         self.player = []   
         self.msg=''   
         self.x = range(100,700)   
         self.y = range(100,500)      
     def getPlayerId(self):   
         return len(self.player)   
     def addClient(self, newclient):      
            self.clients.append(newclient)   
     def delClient(self, client):           
         self.clients.remove(client)      
     def sendAll(self, data):   
         #print data   
         if data.find('')!=-1:   
             proto.transport.write('\0')   
         else:   
             arr = data.split(':')   
             prefix = arr[0]   
             content = arr[1]   
             if prefix.find('player')!=-1:   
                  newPlayer = [content,str(random.randrange(200, 600)),str(random.randrange(150,350)),str(random.randrange(1,5))]   
                  self.player.append(newPlayer)   
                  self.msg = ' 玩家 '+content+' 进入游戏!'   
                  #广播所有玩家的位置   
                  temp = []   
                  playerData = ':::'  
                  for pos in self.player:   
                      temp.append(string.join(pos,'---'))   
                  playerData = playerData+string.join(temp,'***')   
                  for proto in self.clients:   
                      proto.transport.write('[系统]: '+self.msg+'\n')   
                      proto.transport.write(playerData)   
             elif prefix.find('pos')!=-1:   
                 playerName,x,y = content.split('---')   
                 i = 0   
                 for p in self.player:   
                     if p[0]==playerName:   
                         p[1]=x   
                         p[2]=y   
                 for proto in self.clients:   
                     proto.transport.write(data)   
             else:   
                 self.msg = data   
                 for proto in self.clients:   
                      proto.transport.write(self.msg+'\n')   
reactor.listenTCP(8006, GameFactory())   
reactor.run()  
  
  
  // 部分三一个client例子,与前文不相关


代码



from twisted.internet.protocol import ClientCreator, Protocol
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor
import sys
class Sender(Protocol):
    def sendCommand(self, command):
        print "invio", command
        self.transport.write(command)
    def dataReceived(self, data):
        print "DATA", data
PORT = 5005
HOST = 'localhost'
def sendCommand(command):
    def test(d):
        print "Invio ->", command
        d.sendCommand(command)
    c = ClientCreator(reactor, Sender)
    c.connectTCP(HOST, PORT).addCallback(test)
if __name__ == '__main__':
    if len(sys.argv) != 2 or sys.argv[1] not in ['stop', 'next_call', 'force']:
        sys.stderr.write('Usage: %s: {stop|next_call|force}\n' % sys.argv[0])
        sys.exit(1)
    sendCommand(sys.argv[1]+'\n')
    reactor.run()

  

运维网声明 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-59671-1-1.html 上篇帖子: ios远程推送和python版push server相关笔记 下篇帖子: Python框架之Django学习笔记(六)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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