前言
项目上需要实现一个自动发送短信的功能, 由于是内网环境, 所以不能调用阿里之类的短信业务, 于是想着着手从传统的短信猫方式进行实现, 不过某宝上现在已经屏蔽了短信猫
相关的关键词, 不过可以搜USB短信模块
很轻松的就搞到了这块SIM800C的板子, 内置了CH340T进行USB到串口协议的转换.
CH340T驱动
Windows: http://www.wch.cn/downloads/CH341SER_EXE.html Linux: http://www.wch.cn/download/CH341SER_LINUX_ZIP.html
串口指令实现过程
常用指令
指令 | 功能 | 返回值参考 |
| 查询是否入网 | 入网成功: |
| 查看SIM卡中的所有短信 | Unicode编码不带空格的内容 |
HEX模式下发送 | 相当于回车确认 | |
HEX模式下发送 | 相当于取消 |
发送一条中文短信,使用以下指令
AT+CMGF=1
AT+CSMP=17,167,2,25
AT+CSCS="UCS2"
AT+CMGS="00310030003000380036" // 10086 的 unicode 码, 16进制
67E58BE28BDD8D39 //要发送的中文内容"查询话费"的unicode码(16进制无空格)
1A // 切换至HEX模式下发送, 等同于回车确认, 1B等同于ESC取消
需要注意的是发送中文短信时接收的手机号和中文短信内容全部都要使用unicode格式的16进制编码, 测试阶段可以用转换工具来实现, 注意要把转换结果中的空格清除掉
用串口调试工具发送指令测试(Linux下可以用cutecom工具)
手机接收正常, ps:13:56那条是直接用TEXT模式发送包含中文字符短信的效果, 中文是乱码.
使用Python实现上面操作
首先需要pip3 install pyserial
安装操作串口的轮子, 下面是串口的常用操作
import io
import time
import serial
import serial.tools.list_ports
# 字符串转16进制unicode编码
def str2unicode(raw_str):
result = ''
for c in raw_str:
_hex = hex(ord(c))
# 处理数字
if len(_hex) == 4:
_hex = _hex.replace('0x', '00')
else:
_hex = _hex.replace('0x', '')
result += _hex.upper()
return result
port_list = list(serial.tools.list_ports.comports())
target_phone = str2unicode('18500000000')
send_text = str2unicode('你好中文,英文符号,【落款6】')
if len(port_list) == 0:
print('没有可用的串口')
else:
# 使用第一个可用的串口
s = serial.Serial(port_list[0].device, timeout=0.5)
# 创建IO缓存
sio = io.TextIOWrapper(io.BufferedRWPair(s, s))
# 向串口发送字符串命令
sio.write(f'AT+CMGF=1\nAT+CSMP=17,167,2,25\nAT+CSCS="UCS2"\nAT+CMGS="{target_phone}"\n')
sio.flush()
print(''.join(sio.readlines()))
time.sleep(1)
sio.write(send_text+'\n')
sio.flush()
print(''.join(sio.readlines()))
s.write(b'\x1a') # 发送HEX内容1A
sio.flush()
print(''.join(sio.readlines()))
# 关闭串口
s.close()
# 字符串转换
'\u4e2d'.encode('unicode-escape').decode('unicode-escape') # 输出"中"