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

时间:2022-06-26 12:41:17

起源

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

思路

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

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

后来想以一个被动的方式来监控,比如在服务器上装载一个脚本,每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函数来实现

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

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

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

  1. #!/usr/bin/env python
  2. # -*- encoding: utf-8 -*-
  3. '''
  4. @File : server_ip.py
  5. @Time : 2020/04/23 10:08:15
  6. @Author : 吉祥鸟
  7. @GitHub : https://github.com/jixn-hu
  8. @CSDN : https://me.csdn.net/qq_37462361
  9. '''
  10.  
  11. import os
  12. import re
  13. import pyodbc
  14. import time
  15. import socket
  16.  
  17. def now_time():
  18. """
  19. 格式化返回当前时间
  20. :return:
  21. """
  22. now = int(time.time())
  23. local_time = time.localtime(now)
  24. format_now = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
  25. return format_now
  26.  
  27. def open_184_db(db="rreporttask"):
  28. """
  29. 开启本地数据库
  30. :param db: 数据库(默认为rreporttask)
  31. :return: 创建好的数据库连接
  32. """
  33. print(now_time(), '连接184数据库%s' % db)
  34. driver = 'SQL Server'
  35. # 数据库ip
  36. serverName = '******'
  37. # 登陆用户名和密码
  38. userName = '******'
  39. passWord = '******'
  40. # 建立连接并获取cursor
  41. conn = pyodbc.connect(driver=driver, server=serverName,
  42. user=userName, password=passWord, database=db, charset="gbk")
  43. return conn
  44.  
  45. def insert_many(conn, items, table_name):
  46. """
  47. 多条数据插入到数据库(注:插入的数据包含表里的关键字)
  48. :param conn:数据库
  49. :param items:插入的数据列表字典(列表内包含字典类型)
  50. :param table_name:数据库表名
  51. :return:无
  52. """
  53. print(now_time(), "更新数据表{}...".format(table_name))
  54. # print(now_time(),"item:", items)
  55. if items:
  56. cursor = conn.cursor()
  57. sql1 = "insert into %s" % table_name
  58. sql2 = "("
  59. sql3 = ") values("
  60. sql4 = ")"
  61. for key in items[0].keys(): # 拼接sql语句
  62. sql2 += "%s," % key
  63. sql3 += "?,"
  64. # sql4 += "%s=values(%s)," % (key, key)
  65. sql = sql1 + sql2[:-1] + sql3[:-1] + sql4
  66. item_values = []
  67. for item in items:
  68. item_values.append(list(item.values()))
  69. num = len(item_values)
  70. # print(num)
  71. print(now_time(), '一共需要处理数据%s条' % num)
  72. # print(now_time(),"sql:", sql)
  73.  
  74. try:
  75. for i in range(0, num, 1000):
  76. a = min(num, 1000 + i)
  77. # print(item_values[i:a])
  78. cursor.executemany(sql, item_values[i:a])
  79. conn.commit()
  80. print(now_time(), "当前已经处理%s条数据" % a)
  81. except Exception as e:
  82. print(now_time(), '更新数据失败,回滚')
  83. print(e)
  84. conn.rollback()
  85. conn.close()
  86.  
  87. def main():
  88. items = []
  89. item = {}
  90. time.sleep(1)
  91. cmd = 'netstat -n -p tcp | find ":3389"'
  92. command = os.popen(cmd)
  93. r = command.read()
  94. print(r)
  95. zz = r.split("\n")[0].split()
  96. if r=='':
  97. ip = "0000"
  98. else:
  99. local_ip = zz[1]
  100. local_ip = re.sub(r":.*$",'',local_ip)
  101. ip = zz[2]
  102. item["server_ip"]=socket.getaddrinfo(socket.gethostname(),None)[-1][-1][0] # 本地ip
  103. item["sign_ip"] = ip
  104. item["entrytime"] = now_time()
  105. items.append(item)
  106. print(item)
  107. conn = open_184_db()
  108. insert_many(conn,items,"server_sign")
  109.  
  110. if __name__ == "__main__":
  111. main()

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

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

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

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

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

展示

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

就不多说明了

先放个成果图

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

直接上代码

server_sign.py:

  1. #!/usr/bin/env python
  2. # -*- encoding: utf-8 -*-
  3. '''
  4. @File : server_sign.py
  5. @Time : 2020/04/07 10:47:52
  6. @Author : 吉祥鸟
  7. @GitHub : https://github.com/jixn-hu
  8. @CSDN : https://me.csdn.net/qq_37462361
  9. '''
  10.  
  11. import re
  12. import pyodbc
  13. import time
  14. from flask import Flask,render_template
  15.  
  16. app=Flask(__name__)
  17.  
  18. def now_time():
  19. """
  20. 格式化返回当前时间
  21. :return:
  22. """
  23. now = int(time.time())
  24. local_time = time.localtime(now)
  25. format_now = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
  26. return format_now
  27.  
  28. def open_184_db(db="rreporttask"):
  29. """
  30. 开启本地数据库
  31. :param db: 数据库(默认为rreporttask)
  32. :return: 创建好的数据库连接
  33. """
  34. print(now_time(), '连接184数据库%s' % db)
  35. driver = 'SQL Server'
  36. serverName = '******'
  37. # 登陆用户名和密码
  38. userName = '******'
  39. passWord = '******'
  40. # 建立连接并获取cursor
  41. conn = pyodbc.connect(driver=driver, server=serverName,
  42. user=userName, password=passWord, database=db, charset="gbk")
  43. return conn
  44.  
  45. def select_one(conn, sql="select ios_id from ios_main"):
  46. """
  47. 查询信息
  48. :param time:
  49. :param type:
  50. :return:
  51. """
  52. print(now_time(), "正在查询数据库......")
  53. cursor = conn.cursor()
  54. try:
  55. cursor.execute(sql)
  56. result = cursor.fetchall()
  57. conn.commit()
  58. print(now_time(), "数据查询成功")
  59. return result
  60. except:
  61. print(now_time(), '更新数据失败,回滚')
  62. conn.rollback()
  63. conn.close()
  64.  
  65. @app.route('/admin/<name>') # route() 装饰器告诉 Flask 什么样的URL 能触发我们的函数
  66. def hello_world(name):
  67. conn = open_184_db()
  68. data_back = {}
  69. 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")
  70. for data in datas:
  71. if data[1]=='0000' or '3389' in data[1]:
  72. data_back[data[0]]="未连接"
  73. data[1]="无"
  74. else:
  75. data_back[data[0]]="连接ing"
  76. # print(datas)
  77. return render_template("login.html",name=name,datas=datas,data_back=data_back)
  78.  
  79. @app.route('/hal/<name>') # route() 装饰器告诉 Flask 什么样的URL 能触发我们的函数
  80. def hello_world1(name):
  81. return "hellodd {}".format(name)
  82.  
  83. if __name__ == "__main__":
  84. app.run(debug = True,host='0.0.0.0') # 用 run() 函数来让应用运行在本地服务器上

login.html:

  1. <html>
  2. <!-- CSS goes in the document HEAD or added to your external stylesheet -->
  3. <style type="text/css">
  4. table.hovertable {
  5. font-family: verdana,arial,sans-serif;
  6. font-size:11px;
  7. color:#333333;
  8. border-width: 1px;
  9. border-color: #999999;
  10. border-collapse: collapse;
  11. }
  12. table.hovertable th {
  13. background-color:#c3dde0;
  14. border-width: 1px;
  15. padding: 8px;
  16. border-style: solid;
  17. border-color: #a9c6c9;
  18. }
  19. table.hovertable tr {
  20. background-color:#d4e3e5;
  21. }
  22. table.hovertable td {
  23. border-width: 1px;
  24. padding: 8px;
  25. border-style: solid;
  26. border-color: #a9c6c9;
  27. }
  28. </style>
  29. <body>
  30. <h1>服务器登录状态查看</h1>
  31. <table class="hovertable">
  32. <tr>
  33. <th>服务器ip</th>
  34. <th>登录ip</th>
  35. <th>连接时间</th>
  36. <th>连接状态</th>
  37. </tr>
  38. {% for data in datas %}
  39. <tr>
  40. <td>{{ data[0] }}</td>
  41. <td>{{ data[1] }}</td>
  42. <td>{{ data[2] }}</td>
  43. <td>{{ data_back[data[0]] }}</td>
  44. </tr>
  45. {% endfor %}
  46. </table>
  47.  
  48. </body>
  49.  
  50. </html>

思维导图

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

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

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

原文链接:https://www.cnblogs.com/jixn/p/14140532.html