学习使用Twisted框架开发基于TCP的网络应用的方法。该广播系统接收任意客户端的链接请求,并将任意客户端发送给服务器的消息转发给所有其他客户端。本系统是一个基本的实时通信模型。
使用Twisted进行基于传输层TCP的编程时,无须程序员操作Socket的bind、send、receiver等基本原语:而是直接对Twised的Protocol、Factory等类进行编程,定义它们的子类并重写connectionMade、dataReceived进行事件化的TCP编程风格。
服务端:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from twisted.internet.protocol import Protocol
clients = []
class Spreader(Protocol):
def __init__(self, factory):
self.factory = factory
self.connect_id = None
def connectionMade(self):
self.factory.numProtocols = self.factory.numProtocols + 1
self.connect_id = self.factory.numProtocols
self.transport.write((u"欢迎来到Spread Site, 您是第%d个客户端用户!\n" %
(self.connect_id, )).encode('utf8'))
print("new connect: %d" % self.connect_id)
clients.append(self)
def connectionLost(self, reason):
clients.remove(self)
print("lost connect: %d" % self.connect_id)
def dataReceived(self, data):
print("dataReceived() entered!")
if data == "close":
self.transport.loseConnection()
print("%s closed" % self.connect_id)
else:
print("Spreading message from %s : %s" % (self.connect_id, data))
for client in clients:
if client != self:
client.transport.write(data)
print("dataReceived() existed!")
from twisted.internet.protocol import Factory
from twisted.internet.endpoints import TCP4ServerEndpoint
from twisted.internet import reactor
class SpreadFactory(Factory):
def __init__(self):
self.numProtocols = 0
def buildProtocol(self, addr):
return Spreader(self)
# 8007是本服务器的监听端口,建议选择大于1024的端口
endpoint = TCP4ServerEndpoint(reactor, 8007)
endpoint.listen(SpreadFactory())
reactor.run() # 挂起运行
客户端:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.internet import reactor
import sys
import datetime
class Echo(Protocol):
def connectionMade(self):
print("Connected to the server!")
def dataReceived(self, data):
print("Got message from Server: ", data.decode('utf8'))
reactor.callLater(1, self.say_hello)
def connectionLost(self, reason):
print("Disconnected from the server!")
def say_hello(self):
if self.transport.connected:
self.transport.write((u"Hello, I'm a client. %s" %datetime.datetime.now()).encode('utf-8'))
class EchoClientFactory(ClientFactory):
def __init__(self):
self.protocol = None
def startedConnecting(self, connector):
print('Started to connect.')
def buildProtocol(self, addr):
self.protocol = Echo()
return self.protocol
def clientConnectionLost(self, connector, reason):
print('Lost connection. Reason:', reason)
def clientConnectionFailed(self, connector, reason):
print('Connection failed. Reason:', reason)
host = "127.0.0.1"
port = 8007
factory = EchoClientFactory()
reactor.connectTCP(host, port, factory)
reactor.run()
为验证效果客户端可以同时开启多个,也可以使用网络调试助手,协议类型选择TCP Clinet