• Python Twisted


    Python Twisted 框架中 socket通信

    转载:http://blog.csdn.net/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函数来开始服务器。

    简单服务器代码
    
    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()
    服务器实例
    
       # -*- 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世界!
    ")           
             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('<policy-file-request/>')!=-1:   
                 proto.transport.write('<cross-domain-policy><allow-access-from domain="127.0.0.1" to-ports="*"/></cross-domain-policy>')   
             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+'
    ')   
                          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+'
    ')   
                    
    reactor.listenTCP(8006, GameFactory())   
    reactor.run()
    客户端实例(与上例不联系)
    
    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}
    ' % sys.argv[0])
            sys.exit(1)
        sendCommand(sys.argv[1]+'
    ')
        reactor.run()
  • 相关阅读:
    .Net Web开发技术栈
    C#foreach原理
    C#位运算符
    python写12306抢票
    java语法学习
    建立个人知识体系
    struts2静态方法和动态方法调用
    springmvc跳转的几种方式
    JDBC驱动程序的四种方式
    eclipse用axis2发布webserver
  • 原文地址:https://www.cnblogs.com/thbCode/p/4425762.html
Copyright © 2020-2023  润新知