Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1079656
  • 博文数量: 165
  • 博客积分: 3900
  • 博客等级: 中校
  • 技术积分: 1887
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-06 15:15
文章分类

全部博文(165)

文章存档

2020年(3)

2019年(8)

2017年(2)

2016年(8)

2015年(14)

2013年(15)

2012年(32)

2011年(11)

2010年(14)

2009年(7)

2008年(20)

2007年(31)

分类: Python/Ruby

2015-01-28 11:33:35

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()

 

//部分二: 一个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()

阅读(743) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~