• twisted高并发库transport函数处理数据包的些许问题


    还是在学校时间比较多, 能够把时间更多的花在学习上, 尽管工作对人的提升更大, 但是总是没什么时间学习, 而且工作的气氛总是很紧凑, 忙碌, 少了些许激情吧。适应就好了.延续着之前对twisted高并发框架的学习, 自己重新写了一遍代码, 并开始在程序中实现自己的一些想法, 并不局限于最基本的操作, 以及官网上的实例, 因此就引出来了今天的问题.首先, 我需要阐述下我的想法:
    在命令行下启动twisted的服务器端程序, 以及客户端程序.同时在客户端程序中传入三个命令行参数, 其中一定要有close命令, 比如我的传参就是: hello Ryan close.此close控制着连接, 也就是说, 对close参数处理的结果就是关闭服务器-客户端的连接.我原本的设想是分批处理的, understand? 就是说分别对这三个参数进行处理, 前两个参数直接输出就可以, close参数就处理服务器-客户端的连接.但是, 天不随我愿, 先看看代码:
    服务器端:

     1 # coding=utf-8
     2 from twisted.internet.protocol import Protocol
     3 from twisted.internet.protocol import Factory
     4 from twisted.internet.endpoints import TCP4ServerEndpoint
     5 from twisted.internet import reactor
     6 
     7 
     8 clients = []
     9 
    10 
    11 class Spreader(Protocol):  # 派生自协议的协议类
    12     def __init__(self, factory):
    13         self.factory = factory
    14         self._data_buffer = bytes()  # 处理粘包
    15 
    16     def connectionMade(self):
    17         self.factory.numProtocols = self.factory.numProtocols + 1
    18         self.transport.write(
    19             "欢迎来到Spread Site, 你是第%s个客户端用户!
    " % (self.factory.numProtocols)
    20         )
    21         clients.append(self)
    22 
    23     def connectionLost(self, reason):
    24         self.factory.numProtocols = self.factory.numProtocols - 1
    25         clients.remove(self)
    26         print "lost connect: %d" % (self.factory.numProtocols)
    27 
    28     def dataReceived(self, data):
    29         print " ** dataReviced ** "
    30         print data.decode('utf-8')
    31 
    32         self._data_buffer += data
    33         print self._data_buffer
    34         if self._data_buffer.find('close') == -1:
    35             print "loseConnection..."
    36             self.transport.loseConnection()
    37         else:
    38             # self.transport.write(data + " " + "got it!")
    39             # print len(clients)
    40             for client in clients:
    41                 print "no--lose " + self._data_buffer
    42                 client.transport.write(self._data_buffer + " " + "got it")
    43 
    44 
    45 class SpreadFactory(Factory):  # 继承自Factory的自定义协议工厂类
    46     def __init__(self):
    47         self.numProtocols = 0
    48 
    49     def buildProtocol(self, addr):
    50         return Spreader(self)  # 生成协议
    51 
    52 
    53 endpoint = TCP4ServerEndpoint(reactor, 8007)
    54 endpoint.listen(SpreadFactory())  # 开启监听...
    55 reactor.run()

    客户端:

     1 # coding=utf-8
     2 from twisted.internet.protocol import Protocol, ClientFactory
     3 from twisted.internet import reactor
     4 from time import sleep
     5 import sys
     6 
     7 
     8 class Echo(Protocol):
     9     def __init__(self):
    10         self.connected = False
    11 
    12     def connectionMade(self):
    13         self.connected = True
    14 
    15     def connectionLost(self, reason):
    16         self.connected = False
    17 
    18     # 因为transport是非线程安全的, 多访问下可能会引起错误
    19     def routine(self, factory, _d):
    20         # sys.argv[0]获取本身文件路径, 不加索引表示命令行参数  sys.argv其实就是一个元组, 表示用户输入的参数
    21         sleep(1.5)
    22         if factory.protocol and factory.protocol.connected:
    23             print " ** routine ** "
    24             print _d.decode('utf-8')
    25             factory.protocol.transport.write(_d)  # transport为非线程安全函数, 最好调用callfromThread
    26 
    27     def dataReceived(self, data):
    28         print " ** dataReviced ** "
    29         print data.decode('utf-8')
    30 
    31         for index in range(len(_data)):
    32             _d = _data[index]
    33             self.routine(factory, _d)
    34         # reactor.callFromThread(self.routine, factory, data)
    35         # routine(factory)
    36 
    37 
    38 class EchoClientFactory(ClientFactory):
    39     def __init__(self):
    40         self.protocol = None
    41 
    42     def startedConnecting(self, connector):
    43         print "Start to Connect..."
    44 
    45     def buildProtocol(self, addr):
    46         print "Connected..."
    47         self.protocol = Echo()
    48         return self.protocol
    49 
    50     def clientConnectionLost(self, connector, reason):
    51         print "Lost connection. Reason: ", reason
    52 
    53     def clientConnectionFailed(self, connector, reason):
    54         print "Connection is failed, Reason: ", reason
    55 
    56 
    57 host = '127.0.0.1'
    58 port = 8007
    59 factory = EchoClientFactory()  # 自定义协议工厂对象
    60 reactor.connectTCP(host, port, factory)  # 开启TCP连接
    61 # threading.Thread(target=routine, args=(factory,)).start()  # 开启一个线程去执行
    62 _data = sys.argv[1:4]
    63 reactor.run()

    运行截图:

    服务器端:

    客户端:

    我们分析下正好可以得到, 客户端的确是分开发送三个参数的, 但是服务器端的dataReviced函数却是全盘接受, 这就很霸道了。看来我需要在twisted好好地淘淘宝了, 一开始出现这个问题, 我以为是我程序有问题, 搞得我重新研究了twisted的基本通信, 发包, 中断处理...
    好吧, 在这里贡献下我找的资料, 个人觉得twisted网上的资源还是比较少, 去官网吧, 表示找起来很懵逼, 尽管四级过了, 而且网不行...

    twisted(2)--聊天系统

  • 相关阅读:
    【转载】SQL Server跨服务器操作数据库——通过链接服务器(LinkedServer)实现SQL Server远程链接MySql等数据库
    如何正确恢复SQLSERVER的master系统库
    SQL Server Master Database
    Oracle Database “record locked by another user” solution (recommended)
    matlab2021a的快捷键修改
    快速学习新技能
    matlab中数据结构之tables
    记录一个小错误
    matlab数据结构之categorical
    看下不同的代码书写方式
  • 原文地址:https://www.cnblogs.com/zhiyong-ITNote/p/7475437.html
Copyright © 2020-2023  润新知