python 监控服务器是否有人远程登录(详细思路+代码)


Posted in Python onDecember 18, 2020

起源

当同一个远程服务器有多个人使用的时候,想知道服务器是否有人在用,我们不能直接的去登录,因为这样可能会把对方挤下来,这并不友好,所以这里提供一个监控远程服务器是否有人连接的方式

思路

遇到这个问题,想着如何去解决

刚开始的时候,我是想通过一个主动的方式,去监控到服务器是否有人连接,就是说当我想要知道服务器是否有人连接,我通过一个运行一个脚本程序,然后返回给我一个结果,事实证明,我并没有通过这样的思路解决这个问题

后来想以一个被动的方式来监控,比如在服务器上装载一个脚本,每5分钟运行一次脚本,来确定服务器上是否有人连接,不过这也比较消耗资源,后来想到一个方式,就是监控服务器连接和断开的行为,在每次服务器连接和断开的时候,运行脚本来知道服务器是否有人连接

放个流程图

python 监控服务器是否有人远程登录(详细思路+代码)

这里是一整套的监控流程图,包括服务器监控和界面展示

实现

我们有了思路,接下来就是实现的问题

实现起来也比较简单

但是我们需要解决几个问题

  1. 如何知道服务器有没有人连接?
  2. 如何监控远程服务器的连接和断开?

cmd命令netstat监控3389端口

对于第一个问题,如何知道服务器有没有人连接?

这里可以了解一下3389端口(远程桌面的服务端口)和netstat 命令,在windons服务器中,一般是一个远程连接的端口,就是说你可以监控这个端口,来知道服务器有没有人远程连接;而netstat (显示协议统计和当前 TCP/IP 网络连接)是一个cmd命令,我们可以通过它来监控端口情况

比如这里我们要监控3389端口

我们先连接远程连接服务器,打开cmd命令窗口,输入命令:netstat -n -p tcp | find ":3389"

我们就得到一个类似如这样的结果

TCP 10.11.174.373:55311 16.21.315.55:3389 ESTABLISHED

这里有2个ip,一个10.11.174.373,这个是你本地的ip,一个16.21.315.55,这个就是你服务器的ip

但你在服务器上运行这个命令的时候,如果有远程连接,那么就会得到这样的一个结果(当然,你自己连接的也算),当没有人连接的时候,就会得到一个空的,没有任何连接情况

python脚本实现

这里的脚本,我们要实现3个功能:

  1. 获取本地ip
  2. 获取服务器连接状态(ip)
  3. 相关数据存储到数据库

虽然我们使用netstat命令监控3389端口的时候有本地的ip,但是这只是有远程连接的时候有ip信息,但是如果无人连接,那么就获取不到,当然,你也可以自填本地ip,不过这样并不是很好

获取本地ip,这里我们是用python中的socket函数来实现

socket.getaddrinfo(socket.gethostname(),None)[-1][-1][0]

后面的服务器连接,上面有说

数据库存储,也就不多做说明了,直接上下代码(这里数据库,请自行建好)

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File  :  server_ip.py
@Time  :  2020/04/23 10:08:15
@Author :  吉祥鸟
@GitHub :  https://github.com/jixn-hu
@CSDN  :  https://me.csdn.net/qq_37462361
'''


import os
import re
import pyodbc
import time
import socket

def now_time():
  """
  格式化返回当前时间
  :return:
  """
  now = int(time.time())
  local_time = time.localtime(now)
  format_now = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
  return format_now

def open_184_db(db="rreporttask"):
  """
  开启本地数据库
  :param db: 数据库(默认为rreporttask)
  :return: 创建好的数据库连接
  """
  print(now_time(), '连接184数据库%s' % db)
  driver = 'SQL Server'
  # 数据库ip
  serverName = '******'
  # 登陆用户名和密码
  userName = '******'
  passWord = '******'
  # 建立连接并获取cursor
  conn = pyodbc.connect(driver=driver, server=serverName,
             user=userName, password=passWord, database=db, charset="gbk")
  return conn


def insert_many(conn, items, table_name):
  """
  多条数据插入到数据库(注:插入的数据包含表里的关键字)
  :param conn:数据库
  :param items:插入的数据列表字典(列表内包含字典类型)
  :param table_name:数据库表名
  :return:无
  """
  print(now_time(), "更新数据表{}...".format(table_name))
  # print(now_time(),"item:", items)
  if items:
    cursor = conn.cursor()
    sql1 = "insert into %s" % table_name
    sql2 = "("
    sql3 = ") values("
    sql4 = ")"
    for key in items[0].keys(): # 拼接sql语句
      sql2 += "%s," % key
      sql3 += "?,"
      # sql4 += "%s=values(%s)," % (key, key)
    sql = sql1 + sql2[:-1] + sql3[:-1] + sql4
    item_values = []
    for item in items:
      item_values.append(list(item.values()))
    num = len(item_values)
    # print(num)
    print(now_time(), '一共需要处理数据%s条' % num)
    # print(now_time(),"sql:", sql)

    try:
      for i in range(0, num, 1000):
        a = min(num, 1000 + i)
        # print(item_values[i:a])
        cursor.executemany(sql, item_values[i:a])
        conn.commit()
        print(now_time(), "当前已经处理%s条数据" % a)
    except Exception as e:
      print(now_time(), '更新数据失败,回滚')
      print(e)
      conn.rollback()
  conn.close()


def main():
  items = []
  item = {}
  time.sleep(1)
  cmd = 'netstat -n -p tcp | find ":3389"'
  command = os.popen(cmd)
  r = command.read()
  print(r)
  zz = r.split("\n")[0].split()
  if r=='':
    ip = "0000"
  else:
    local_ip = zz[1]
    local_ip = re.sub(r":.*$",'',local_ip)
    ip = zz[2]
  item["server_ip"]=socket.getaddrinfo(socket.gethostname(),None)[-1][-1][0] # 本地ip
  item["sign_ip"] = ip
  item["entrytime"] = now_time()
  items.append(item)
  print(item)
  conn = open_184_db()
  insert_many(conn,items,"server_sign")
  

if __name__ == "__main__":
  main()

你可以把这个python脚本,打包成exe,然后放到服务器上,设置触发条件,当有人连接和断开服务器的时候,运行这个脚本

至于如何设置这个触发器,这就是第二个问题了,如何监控远程服务器的连接和断开?

这里可以百度下,windons自带的任务计划程序,通过这个我们可以设置exe服务器连接和断开的时,运行exe脚本,放个图,之后的自行摸索下

python 监控服务器是否有人远程登录(详细思路+代码)

其实到这里,基本就是结束了,详细的思路和主要的实现,也都有了,我们可以直接查询数据库就能的知道服务器连接的情况

展示

不过后面为了更方便看,后面我自己又使用flask做了一个界面展示

就不多说明了

先放个成果图

python 监控服务器是否有人远程登录(详细思路+代码)

直接上代码

server_sign.py:

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File  :  server_sign.py
@Time  :  2020/04/07 10:47:52
@Author :  吉祥鸟
@GitHub :  https://github.com/jixn-hu
@CSDN  :  https://me.csdn.net/qq_37462361
'''

import re
import pyodbc
import time
from flask import Flask,render_template

app=Flask(__name__)

def now_time():
  """
  格式化返回当前时间
  :return:
  """
  now = int(time.time())
  local_time = time.localtime(now)
  format_now = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
  return format_now

def open_184_db(db="rreporttask"):
  """
  开启本地数据库
  :param db: 数据库(默认为rreporttask)
  :return: 创建好的数据库连接
  """
  print(now_time(), '连接184数据库%s' % db)
  driver = 'SQL Server'
  serverName = '******'
  # 登陆用户名和密码
  userName = '******'
  passWord = '******'
  # 建立连接并获取cursor
  conn = pyodbc.connect(driver=driver, server=serverName,
             user=userName, password=passWord, database=db, charset="gbk")
  return conn


def select_one(conn, sql="select ios_id from ios_main"):
  """
  查询信息
  :param time:
  :param type:
  :return:
  """
  print(now_time(), "正在查询数据库......")
  cursor = conn.cursor()
  try:
    cursor.execute(sql)
    result = cursor.fetchall()
    conn.commit()
    print(now_time(), "数据查询成功")
    return result
  except:
    print(now_time(), '更新数据失败,回滚')
    conn.rollback()
  conn.close()



@app.route('/admin/<name>') # route() 装饰器告诉 Flask 什么样的URL 能触发我们的函数
def hello_world(name):
  conn = open_184_db()
  data_back = {}
  datas = select_one(conn,"select server_ip,sign_ip,entrytime from(select *,ROW_NUMBER()over(partition by server_ip order by entrytime desc)rank from rreporttask..server_sign) as z where rank=1 order by server_ip")
  for data in datas:
    if data[1]=='0000' or '3389' in data[1]:
      data_back[data[0]]="未连接"
      data[1]="无"
    else:
      data_back[data[0]]="连接ing"
  # print(datas)
  return render_template("login.html",name=name,datas=datas,data_back=data_back)


@app.route('/hal/<name>') # route() 装饰器告诉 Flask 什么样的URL 能触发我们的函数
def hello_world1(name):
  return "hellodd {}".format(name)

if __name__ == "__main__":
  app.run(debug = True,host='0.0.0.0') # 用 run() 函数来让应用运行在本地服务器上

login.html:

<html>
  <!-- CSS goes in the document HEAD or added to your external stylesheet -->
<style type="text/css">
  table.hovertable {
  font-family: verdana,arial,sans-serif;
  font-size:11px;
  color:#333333;
  border-width: 1px;
  border-color: #999999;
  border-collapse: collapse;
  }
  table.hovertable th {
  background-color:#c3dde0;
  border-width: 1px;
  padding: 8px;
  border-style: solid;
  border-color: #a9c6c9;
  }
  table.hovertable tr {
  background-color:#d4e3e5;
  }
  table.hovertable td {
  border-width: 1px;
  padding: 8px;
  border-style: solid;
  border-color: #a9c6c9;
  }
  </style>
  <body>
   <h1>服务器登录状态查看</h1>
   <table class="hovertable">
     <tr>
      <th>服务器ip</th>
      <th>登录ip</th>
      <th>连接时间</th>
      <th>连接状态</th>
     </tr>
     {% for data in datas %}
      <tr>
        <td>{{ data[0] }}</td>
        <td>{{ data[1] }}</td>
        <td>{{ data[2] }}</td>
        <td>{{ data_back[data[0]] }}</td>
      </tr>
     {% endfor %}
   </table>

  </body>
  
</html>

思维导图

最后,放一个思维导图,供参考

python 监控服务器是否有人远程登录(详细思路+代码)

以上就是python 监控服务器是否有人远程登录(详细思路+代码)的详细内容,更多关于python 监控服务器的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python实现二分查找与bisect模块详解
Jan 13 Python
使用Python写一个小游戏
Apr 02 Python
Python随机函数random()使用方法小结
Apr 29 Python
详解Python 数据库的Connection、Cursor两大对象
Jun 25 Python
python中使用print输出中文的方法
Jul 16 Python
Python实现获取汉字偏旁部首的方法示例【测试可用】
Dec 18 Python
python 阶乘累加和的实例
Feb 01 Python
pytorch常见的Tensor类型详解
Jan 15 Python
Pytorch模型转onnx模型实例
Jan 15 Python
Python常用编译器原理及特点解析
Mar 23 Python
详解python tkinter 图片插入问题
Sep 03 Python
Django修改app名称和数据表迁移方案实现
Sep 17 Python
细说NumPy数组的四种乘法的使用
Dec 18 #Python
如何通过python检查文件是否被占用
Dec 18 #Python
python 实现端口扫描工具
Dec 18 #Python
Python-split()函数实例用法讲解
Dec 18 #Python
Python+Opencv实现把图片、视频互转的示例
Dec 17 #Python
python 利用jieba.analyse进行 关键词提取
Dec 17 #Python
Python基础进阶之海量表情包多线程爬虫功能的实现
Dec 17 #Python
You might like
测试您的 PHP 水平的题目
2007/05/30 PHP
PHP批量检测并去除文件BOM头代码实例
2014/05/08 PHP
php使用Image Magick将PDF文件转换为JPG文件的方法
2015/04/01 PHP
PHP时间和日期函数详解
2015/05/08 PHP
PHP自定义函数获取URL中一级域名的方法
2016/08/23 PHP
慎用 somefunction.prototype 分析
2009/06/02 Javascript
前端开发的开始---基于面向对象的Ajax类
2010/09/17 Javascript
Node调试工具JSHint的安装及配置教程
2014/05/27 Javascript
jQuery防止重复绑定事件的解决方法
2016/05/14 Javascript
浅谈JavaScript的内置对象和浏览器对象
2016/06/03 Javascript
利用Node.JS实现邮件发送功能
2016/10/21 Javascript
jQuery密码强度验证控件使用详解
2017/01/05 Javascript
javascript防篡改对象实例详解
2017/04/10 Javascript
JS基于正则实现数字千分位用逗号分隔的方法
2017/06/16 Javascript
Vue数据监听方法watch的使用
2018/03/28 Javascript
探秘vue-rx 2.0(推荐)
2018/09/21 Javascript
vue项目打包之开发环境和部署环境的实现
2020/04/23 Javascript
[01:18:45]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第三场2月1日
2021/03/11 DOTA
[08:08]DOTA2-DPC中国联赛2月28日Recap集锦
2021/03/11 DOTA
python下函数参数的传递(参数带星号的说明)
2010/09/19 Python
python开发利器之ulipad的使用实践
2017/03/16 Python
Django shell调试models输出的SQL语句方法
2019/08/29 Python
Python 获取项目根路径的代码
2019/09/27 Python
使用pandas的box_plot去除异常值
2019/12/10 Python
简单了解Django ORM常用字段类型及参数配置
2020/01/07 Python
python实现文法左递归的消除方法
2020/05/22 Python
Python检测端口IP字符串是否合法
2020/06/05 Python
Html5与App的通讯方式详解
2019/10/24 HTML / CSS
英国水族馆和池塘用品购物网站:Warehouse Aquatics
2019/08/29 全球购物
js实现弹框效果
2021/03/24 Javascript
旅游专业职业生涯规划范文
2014/01/13 职场文书
港澳通行证委托书怎么写
2014/08/02 职场文书
2015年汽车销售员工作总结
2015/07/24 职场文书
大学学习委员竞选稿
2015/11/20 职场文书
德劲DE1107指针试高灵敏度全波段收音机机评
2022/04/05 无线电
httpclient调用远程接口的方法
2022/08/14 Java/Android