Python Twisted框架中socket通讯

转自 : https://blog.csdn.net/qiaojun_peng/article/details/38846719

转载自:http://www.cnblogs.com/sevenyuan/archive/2010/11/18/1880681.html

第一部分:

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函数来开始服务器。

[python]  view plain  copy
  1. # -*- coding:utf-8 -*-  
  2. from twisted.internet import protocol, reactor  
  3. import datetime  
  4.   
  5. # 定义Protocol类  
  6. class TSServProtocol(protocol.Protocol):  
  7.     def connectionMade(self):  
  8.         clnt = self.clnt = self.transport.getPeer().host  
  9.         print '...connected from: ', clnt  
  10.       
  11.     def dataReceived(self, data):  
  12.         print data  
  13.         self.transport.write('[%s] %s' % (datetime.datetime.now(), data))  
  14.   
  15.   
  16. # 实例化Factory  
  17. factory = protocol.Factory()  
  18. # 设置factory的protocol属性以便它知道使用哪个protocol与客户端通讯(这就是所谓的自定的protocol)  
  19. factory.protocol = TSServProtocol  
  20. print 'waiting for connection...'  
  21. # 监听指定的端口  
  22. reactor.listenTCP(8008, factory)  
  23. # 开始运行主程序  
  24. reactor.run()</span>  
为你的处理目的而写一个自定义的protocol是很容易的。模块twisted.protocols.basic中包含了几个有用的已存在的 protocol,其中的LineReceiver执行dataReceived并在接受到了一个完整的行时调用事件处理器lineReceived。如果当你在接受数据时除了使用lineReceived,还要做些别的,那么你可以使用LineReceiver定义的名为rawDataReceived 事件处理器。下面是一使用LineReceiver的服务器例子:

[python]  view plain  copy
  1. from twisted.internet import reactor  
  2. from twisted.internet.protocol import Factory  
  3. from twisted.protocols.basic import LineReceiver  
  4.   
  5. class SimpleLogger(LineReceiver):  
  6.   
  7.     def connectionMade(self):  
  8.         print 'Got connection from'self.transport.client  
  9.     def connectionLost(self, reason):  
  10.         print self.transport.client, 'disconnected'  
  11.     def lineReceived(self, line):  
  12.         print line  
  13.   
  14. factory = Factory()  
  15. factory.protocol = SimpleLogger  
  16. reactor.listenTCP(1234, factory)  
  17. reactor.run()  


第二部分: 一个server实例

[python]  view plain  copy
  1. # -*- coding: UTF-8 -*-     
  2. # Twisted MMORPG     
  3. from twisted.internet.protocol import Factory     
  4. from twisted.protocols.basic import LineOnlyReceiver     
  5. from twisted.internet import reactor     
  6. import random     
  7. import string     
  8.       
  9. class Game(LineOnlyReceiver):         
  10.    def lineReceived(self, data):       
  11.        self.factory.sendAll("%s" % (data))      
  12.    def getId(self):             
  13.        return str(self.transport.getPeer())     
  14.    def connectionMade(self):             
  15.        print "New User Login:"self.getId()       
  16.        self.transport.write("欢迎来到MMO世界!\n")             
  17.        self.factory.addClient(self)         
  18.    def connectionLost(self, reason):             
  19.        self.factory.delClient(self)  
  20.               
  21. class GameFactory(Factory):         
  22.      protocol = Game         
  23.      def __init__(self):             
  24.          self.clients = []     
  25.          self.player = []     
  26.          self.msg=''      
  27.          self.x = range(100,700)     
  28.          self.y = range(100,500)        
  29.      def getPlayerId(self):     
  30.          return len(self.player)     
  31.      def addClient(self, newclient):        
  32.             self.clients.append(newclient)      
  33.      def delClient(self, client):             
  34.          self.clients.remove(client)         
  35.      def sendAll(self, data):     
  36.          #print data     
  37.          if data.find('<policy-file-request/>')!=-1:     
  38.              proto.transport.write('<cross-domain-policy><allow-access-from domain="127.0.0.1" to-ports="*"/></cross-domain-policy>\0')     
  39.          else:     
  40.              arr = data.split(':')     
  41.              prefix = arr[0]     
  42.              content = arr[1]     
  43.              if prefix.find('player')!=-1:     
  44.                   newPlayer = [content,str(random.randrange(200600)),str(random.randrange(150,350)),str(random.randrange(1,5))]     
  45.                   self.player.append(newPlayer)     
  46.                   self.msg = ' 玩家 '+content+' 进入游戏!'      
  47.                   #广播所有玩家的位置     
  48.                   temp = []     
  49.                   playerData = ':::'    
  50.                   for pos in self.player:     
  51.                       temp.append(string.join(pos,'---'))     
  52.                   playerData = playerData+string.join(temp,'***')     
  53.                   for proto in self.clients:     
  54.                       proto.transport.write('[系统]: '+self.msg+'\n')     
  55.                       proto.transport.write(playerData)     
  56.              elif prefix.find('pos')!=-1:     
  57.                  playerName,x,y = content.split('---')     
  58.                  i = 0     
  59.                  for p in self.player:     
  60.                      if p[0]==playerName:     
  61.                          p[1]=x     
  62.                          p[2]=y     
  63.                  for proto in self.clients:     
  64.                      proto.transport.write(data)     
  65.              else:     
  66.                  self.msg = data     
  67.                  for proto in self.clients:     
  68.                       proto.transport.write(self.msg+'\n')     
  69.                   
  70. reactor.listenTCP(8006, GameFactory())     
  71. reactor.run()  


第三部分:Client列子,与第一部分对应

[python]  view plain  copy
  1. # -*- coding:utf-8 -*-  
  2. import datetime  
  3. import sys  
  4. from twisted.internet import protocol, reactor  
  5. from twisted.protocols.basic import LineReceiver  
  6.   
  7.   
  8. HOST = 'localhost'  
  9. PORT = 8008  
  10.   
  11. class TSClntProtocol(protocol.Protocol):  
  12.     def sendData(self):  
  13.         data = raw_input('> ')  
  14.         if data:  
  15.             print '...sending %s...' % data  
  16.             self.transport.write(data)  
  17.         else:  
  18.             self.transport.loseConnection()  
  19.       
  20.     def connectionMade(self):  
  21.         self.sendData()  
  22.           
  23.     def dataReceived(self, data):  
  24.         print data  
  25.         self.sendData()  
  26.   
  27.   
  28. class TSClntFactory(protocol.ClientFactory):  
  29.     protocol = TSClntProtocol  
  30.     clientConnectionLost = clientConnectionFailed = lambda self, connector, reason: reactor.stop()  
  31.       
  32.       
  33. reactor.connectTCP(HOST, PORT, TSClntFactory())  
  34. reactor.run()  


猜你喜欢

转载自blog.csdn.net/xiaoxianerqq/article/details/80051673