本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、简介
因为之前写过一篇树莓派使用Socket发送数据至PC并存入数据库,但由于其用的是局域网连接,多有不便,正好最近从阿里云通过高校计划领取了免费的云服务器,就想着能不能通过socket连接云服务器,存到云服务器的数据库中。
二、前情提要
以下大概属于大家实现本文案例的一些准备工作和初步了解。
准备工作:
1、首先我们要做到树莓派和ECS
中均有Python
编译环境。一般树莓派会自带Thony
,这个就够用了,ECS
服务器一般没有编译环境,需要自己安装,我们只需要从软件商店里面搜索Python
,安装IDLE3
就够用了。
2、两者均可使用
VNC
远程连接,方便操作
3、ECS中需要提前安装好
MySQL
数据库,并可以通过Navicat实现远程连接
4、ECS
需要在安全组中开放端口,这个端口号可以自己设置,只要不和常用的几个冲突即可,像我这里选用的就是2222
5、
ECS
需要提前安装好pymysql
库,插入数据库的时候需要用到它对mysql
数据库进行操作,我选择的方式是先安装pip
,然后再通过pip
安装pymsql
,当然也可以从GitHub
直接下载下来,然后解压,大家可以自由选择
wget https://bootstrap.pypa.io/get-pip.py
sudo python3 get-pip.py
# 安装成功后 查看pip的版本
pip --version
# 安装pymsql
pip install pymysql
6、开启ECS
的防火墙,这算是一个槽点,必须开启防火墙才能进行连接,但是成功连接上之后,把防火墙关了也不受影响了,但是一开始必须开启防火墙才行
# 1,查看防火墙状态
systemctl status firewalld.service
# 2,开启防火墙
systemctl start firewalld.service
# 3,关闭防火墙
systemctl stop firewalld.service
# 4,禁用防火墙
systemctl disable firewalld.service
三、软件准备
老规矩,先启动服务端,再启动客户端,HOST
为服务器的IP地址,但这个连接ECS
还有些特殊,服务端HOST
写的是云服务器的内网地址,而客户端写的则是云服务器的公网地址。
1、raspberrypi.py(客户端)
#import socket
from socket import *
import time
HOST = '公网地址'
PORT = 2222
BUFSIZ = 1024
ADDR = (HOST,PORT)
try:
mySocket = socket(AF_INET,SOCK_STREAM)
mySocket.connect(ADDR)
print("连接到服务器")
except : ##连接不成功,运行最初的ip
print ('连接不成功')
while True:
#发送消息
msg = '9'
#编码发送
mySocket.send(msg.encode("utf-8"))
print("发送完成")
time.sleep(10)
if msg == "over":
mySocket.close()
print("程序结束\n")
exit()
print("程序结束\n")
2、ECS.py(服务端)
import socket
import pymysql
import time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '内网地址'
PORT = 2222
#绑定socket
s.bind((HOST, PORT))
s.listen(10)
# 打开数据库连接
db = pymysql.connect(
host='localhost',
port=3306,
user='root',
passwd='tangjiao903',
db='centosdb',
charset='utf8'
)
print("数据库开启")
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()
sqltime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
while True:
# 接收客户端连接
print("等待连接....")
client, address = s.accept()
print("新连接")
print("IP is %s" % address[0])
print("port is %d\n" % address[1])
while True:
# 读取消息
msg = client.recv(1024)
# 把接收到的数据进行解码
print(msg.decode("utf-8"))
print("读取完成")
# SQL 插入语句
# sql = "INSERT INTO MAGNETISM(MTIME , MFLAG) VALUES ('%s','%s')" % (sqltime, msg.decode("utf-8"))
sql = "INSERT INTO magnetism(MFLAG) VALUES ('%s')" % (msg.decode("utf-8"))
try:
# 执行sql语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
print("insert success!")
except:
# 如果发生错误则回滚
db.rollback()
print("insert fail!")
time.sleep(10)
if msg == "over":
client.close()
s.close()
# 关闭数据库连接
db.close()
print("程序结束\n")
exit()
四、遇到的问题
1、报错name ‘AF_INET‘ is not defined。/TypeError: ‘module‘ object is not callable
解决方案:将import socket,改为from socket import *,还有一种说法是文件名命名的原因,命名成socket.py,导致其无法识别,将其更改即可,但是我尝试了一下,并没有解决,最后还是通过更改引用包的形式解决的。
#import socket
from socket import *
from time import *
2、Error【1146】:Table 'xxx.xxx' doesn't exist
解决方案:
- 检查数据库名
- 检查数据库表是否存在
- 检查表名是否正确,且区分大小写
我这里就是因为表名大小写的问题造成的。