最近剛剛接觸 twisted 庫,感覺twisted 庫的設計模式和平時接觸的socket 通信很大不同, 感覺有點不大適應,爲了增加自己對twisted 的適應度, 同時也熟悉一下心跳包的機制。
特地寫了一個 基於twisted 庫的 TCP 服務器 心跳包 demo。
以供練習之用。 同時也和大家分享 python 編程心得
demo 特性描述:
1 TCP服務器支持多客戶端連接, 每次客戶端連接之後,直接將客戶端信息(IP 地址, 端口號)存儲到字典當中。 並且啓動Svr_unit 程序定時器(30s 響應)
2 服務器接受到數據之後, 分析 發送數據段的信息 (IP地址,端口號) , 如果數據信息與字典的數據匹配, 則直接調用 對於的Svr_unit 進行數據處理(返回發送數據), 同時刷新定時器,重新定時
3 如果Svr_unit 對象定時器超時, 則調用服務器的函數,將自身從服務器 中的字典中自我移除, 提示連接斷開
<span style="font-size:14px;"><span style="font-size:18px;"># -*- coding: utf-8 -*-
"""
Created on 2014/11/25
@author: LEO
"""
from twisted.internet import protocol, reactor
import threading
class Svr(object):
def __init__(self):
reactor.listenTCP(8000 , svrfactory())
def Run(self):
reactor.run()
class svrfactory(protocol.Factory):
def buildProtocol(self, addr):
return Serveport()
class Serveport(protocol.Protocol):
def __init__(self):
self._svrunit = dict()
def connectionMade(self):
ipinfo = self.transport.getPeer()
print ipinfo,'connect server'
self.Deal_connect(ipinfo)
def connectionLost(self, reason):
print 'connection lost for : \n' , reason
def dataReceived(self, data):
pipv4 = self.transport.getPeer()
if data is not None:
self.Deal_datarecieve(data , pipv4)
def dataSend(self, data):
if data is None:
return
else:
self.transport.write(data)
def Deal_connect(self , pipv4):
if pipv4 not in self._svrunit:
print 'new a client' , pipv4
pclient = Svr_unit( self , pipv4)
self._svrunit[pipv4] =pclient
def Deal_disconnect(self ):
pass
def Deal_datarecieve(self, data, pipv4):
if pipv4 in self._svrunit:
print 'recieve data from ' , pipv4
self._svrunit[pipv4].Echo(data)
else:
print 'warming:'
print 'recieve data from unknow client' ,pipv4
def Remove_client(self, pipv4):
if pipv4 in self._svrunit:
print 'warming: '
print pipv4 , 'is over time '
del self._svrunit[pipv4]
else:
print 'not found the client in the list '
class Svr_unit(object):
def __init__(self, svrhanle ,pipv4):
self.srv = svrhanle
self.ipv4 = pipv4
# start the timer for heatbeat
self.timer = threading.Timer(30, self.Terminate )
self.timer.start()
def Echo(self , data):
if data is not None:
self.Reset_timer()
pstr = 'echo from server : '+ data
self.srv.dataSend(pstr)
def Reset_timer(self):
"""
reset the anticlock once class had recieve the heart beat signal """
print 'reset the timer for heart beat '
self.timer.cancel()
self.timer = threading.Timer(20, self.Terminate )
self.timer.start()
def Terminate(self):
'''over time operation :
remove current class from server list , so that it would never recieve any
data '''
self.srv.Remove_client(self.ipv4)
def main():
svrend = Svr()
svrend.Run()
if __name__ == '__main__':
main()
</span></span>
python 編程心得:
1 相比於C++ 編程, python 這種動態腳本語言來實現 面向對象的思想, 那簡直是飛一般的感覺。 類之間的相關調用那是行雲流水般的舒適。 相互嵌套調用的實現也是非常簡單。 用非常少的代碼,可是快速實現相當複雜的邏輯關係。 非常棒。
2 對於python 的編程命令方式, 現在感覺自己非常錯亂, 不同的庫,採用不同的命名規則, 自己的代碼中的變量和函數命名也相當混亂。 希望有人能推薦一種比較適合python 的命名方法,能夠解決 python 類內 私有和公有 封裝的命名方式