windows監控——再見zmq

若是不動手實踐,總會把複雜的問題想簡單。其實也不復雜,只是用得少,不熟悉。前端

仍是這個題目,已經寫到了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)
    
相關文章
相關標籤/搜索