若是不動手實踐,總會把複雜的問題想簡單。其實也不復雜,只是用得少,不熟悉。前端
仍是這個題目,已經寫到了version5.1。起初很隨便地用了本身不太瞭解的socket通訊,稀裏糊塗地完成了功能。可是到後期改代碼就很困難了。索性一不作二不休,改爲zmq通訊,畢竟用過。python
可是不會用zmq進行一對多的通訊,客戶端開多了,老是會弄亂send和recv。只能在每一個循環中,只設置一對send,recv。數據庫
本想偷懶不用正則匹配,結果偷雞不成蝕把米,zmq混亂了。仍是老老實實用正則匹配從前臺獲取週期。json
使用zmq通訊最大的感覺就是,必定要弄清消息的「前因後果」,client和server的send和recv必定要完美匹配,纔不會出錯。windows
廢話說完,上乾貨!服務器
server.pyapp
#! /usr/bin/env python #coding=utf-8 ''' fileName: server.py 數據發送方式:zmq ''' import zmq import time import json from Queue import Queue import threading import pymongo import re # 默認週期 cycle = 10 # 生產者進程 class Producer(threading.Thread): def __init__(self, t_name, processdata): threading.Thread.__init__(self, name=t_name) self.data=processdata def run(self): print "%s: %s is producing in the queue!/n" %(time.ctime(), self.getName()) recvMassage() # 接收數據 def recvMassage(): context = zmq.Context() socket = context.socket(zmq.REP) socket.bind("tcp://*:5555") while (True): message = socket.recv() print "message from client:", message if '@' in message: # 接收到前端更改週期 mode = re.compile(r'\d+') c = mode.findall(message) global cycle cycle = int (c[0]) print 'Now, the cycle is ',cycle socket.send('ok') else: # 接收客戶端監控信息 load = json.loads(message) info = dict(load) print type(info) handleData(info) # 處理監控信息 socket.send(str(cycle)) # 返回當前週期 # 處理監控到的信息 def handleData(info): # 連接數據庫 conn = pymongo.Connection("localhost", 27017) db = conn['networkSecurity'] systemInfo = db['systemInfo'] # 構造dict數據 message = {'IP':info[u'IP'],'CPUstate':info[u'CPUstate'],'Memorystate':info[u'Memorystate'], 'PortState':info[u'PortState'],'ProcessName':info[u'ProcessName']} print 'Client said :\nIP:%s\nCPUstate:%s\nMemorystate:%s\nPortState:%s\nProcessName:%s'%(message['IP'],message['CPUstate'],message['Memorystate'],message['PortState'],message['ProcessName']) # 將數據放入隊列 processdata.put(message) # 將數據存入數據庫 systemInfo.insert(message) print 'success to store the data!' #消費者 class Consumer(threading.Thread): def __init__(self, t_name,processdata): threading.Thread.__init__(self, name=t_name) def run(self): print "%s: %s is consuming in the queue!/n" %(time.ctime(), self.getName()) message = processdata.get() # print 'the message in the queue is : ',message # print type(message) monitorSystem(message) # 黑白名單匹配,info爲字典 def monitorSystem(info): warning = 0 whiteList = ['cmd.exe'] blackList = ['sublime_text.exe'] # for info in systemInfo.find(): # print info IP = info['IP'] processName = info['ProcessName'] for process in processName: if process in blackList: warning = 1 print 'Process %s in black list is running in IP %s ! '%(process,IP) for process in whiteList: if process not in processName: warning = 1 print 'Process %s in white list is not running in IP %s ! '%(process,IP) if warning == 0: print 'Host %s is running legally ! '%IP if __name__ == '__main__': # 處理隊列 processdata=Queue() # 生產進程:接受數據 producer = Producer('Pro.', processdata) # 消費進程:處理數據,黑白名單匹配 consumer = Consumer('Con.', processdata) producer.start() consumer.start() producer.join() consumer.join()
client.pysocket
#! /usr/bin/env python #coding=utf-8 ''' fileName:client.py 監控windows信息:CPU佔有率,內存佔有率,端口開放狀況,當前進程名稱 數據格式: {'IP':getIp(),'CPUstate':getCPUState(),'Memorystate':getMemoryState(), 'PortState':getPortState(),'ProcessName':getProcessName()} ''' import zmq import psutil import json import socket import thread import time # 向服務器發送監控信息 def sendMessage(portState): context = zmq.Context() print "Connecting to server..." socket = context.socket(zmq.REQ) socket.connect ("tcp://192.168.111.135:5555") # 這裏的IP爲服務器IP mymessage = json.dumps(packMessage(portState)) socket.send(mymessage) # 發送監控信息 info = socket.recv() # 收到週期 print "Received reply: ",info c = json.loads(info) global cycle cycle = int(c) # 構造數據包 def packMessage(portState): message = {'IP':getIp(),'CPUstate':getCPUState(),'Memorystate':getMemoryState(), 'PortState':portState,'ProcessName':getProcessName()} print 'My message is :\nIP:%s\nCPUstate:%s\nMemorystate:%s\nPortState:%s\nProcessName:%s'%(message['IP'],message['CPUstate'],message['Memorystate'],message['PortState'],message['ProcessName']) return message # 獲取本機IP def getIp(): myname = socket.getfqdn(socket.gethostname()) myaddr = socket.gethostbyname(myname) return myaddr # 獲取CPU使用率 def getCPUState(interval=1): return (str(psutil.cpu_percent(interval)) + "%") # 獲取內存使用率 def getMemoryState(): mem_rate = 0 for pnum in psutil.pids(): p = psutil.Process(pnum) mem_rate = mem_rate + p.memory_percent() return "%.2f%%"%mem_rate # 輸入IP和端口號,掃描判斷端口是否開放 def socket_port(ip,port,portList): try: if port >= 65535: print u'端口掃描結束' s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) result = s.connect_ex((ip,port)) if result == 0: lock.acquire() portList.append(port) lock.release() s.close() except: print u'端口掃描異常' # 輸入IP,掃描IP的0-65534端口狀況 def ip_scan(ip): portList = [] socket.setdefaulttimeout(3) try: for i in range(0,65534): thread.start_new_thread(socket_port,(ip,int(i),portList)) # 返回全部開放的端口號 return portList except: print u'掃描ip出錯' # 獲取正在運行的進程名稱 def getProcessName(): ProcessNameList = [] for pnum in psutil.pids(): p = psutil.Process(pnum) ProcessNameList.append(p.name()) return ProcessNameList if __name__ == '__main__': global cycle cycle = 60 while(True): # 當前端口開放狀態 myIP = getIp() lock = thread.allocate_lock() portState = ip_scan(myIP) # 主要函數——發送監控信息 sendMessage(portState) # 發送週期 print 'The cycle is',cycle time.sleep(cycle)