一、项目背景
先说下我程序中Socket的用途吧,这样也好参照。我是想用手机的小程序跟阿里云服务器(Windows系统,非Linux系统)上的python程序进行通信,我的小程序会不定期拍摄照片上传到OSS云存储上,同时使用request(POST)的http请求将上传的图片的地址发送给阿里云上的python程序,然后python程序对地址的照片进行下载处理。
过程当中,我设想的是在python程序使用Socket创建TCP服务端,然后使用while循环来一直接收小程序发送的数据,就是想着不用管阿里云上的程序。中间试了很多次,各种心跳程序啥的都试了,发现都不太适合,因为我想的就是我不发送数据的时候,云服务器程序就一直等着,有数据时就接收。
二、代码
主要是通过给套接字对象设置超时,以及运用try,except报错跳转程序。
我直接写我怎么实现的吧。。。。
from socket import *
from threading import Thread
# 这个函数运行 是为了怕除阻塞外的其他地方报错 导致程序终止写的
def loop_socket_run():
try:
socket_run()
except BaseException as e:
print("错误是:",e)
finally:
# 这个打印只是为了起一个标志的作用 可以不要
print("re_socket")
loop_socket_run()
def socket_run():
while True:
# 创建服务器端套接字对象
sever_socket = socket(AF_INET, SOCK_STREAM)
# 创建连接超时为10s (如果超过10s没有客户端连接,就会报错,这个时间可以根据自己的情况改)
sever_socket.settimeout(10)
# 绑定端口
sever_socket.bind(('填写你的地址', 填写你的端口)) # 服务器端口
# 监听
sever_socket.listen()
try:
# 等待客户端的连接 当没有客户端接入,阻塞超时(10s)就会在此处报错,就会执行except下面的程序
client_socket, client_addr_info = sever_socket.accept()
except:
# 如果没有客户端连接,超时10s,就关闭套接字对象
sever_socket.close()
# 重新进入函数(重新创建套接字对象 并等待连接)
socket_run()
# 如果接收到客户端的连接
recv_data = client_socket.recv(1024)
print("接收到的数据:",recv_data.decode('utf-8'))
# 这是对小程序http请求的response 返回的是"OK"
response_headers = "HTTP/1.1 200 OK\r\n" # 200 表示找到这个资源
response_headers += "\r\n" # 空一行与body隔开
response_body = "OK" # 这个数据是小程序可以收到的
response = response_headers + response_body
client_socket.send(response.encode('utf-8'))
# 最后关闭连接
client_socket.close()
if __name__ == "__main__":
th1 = Thread(target = loop_socket_run)
th1.start()
整个程序亲测有效,这个程序目前我在云服务器上开了1天没终止,还在持续测试。
但是当中遇到一个问题,这个程序我运行了1天后,我在python程序的控制台中查看打印的标志,发现有的时候没有客户端连接,但是accept会自己莫名的连接上了,并且接收的数据为None。但是后面的又都正常了,目前还不知道是什么原因,欢迎交流!!!