python 3.5构建WINDOWS推送服务
import ConfigParser
import os
import sys cf = ConfigParser.ConfigParser()
#绝对路径获取
ABSPATH=os.path.abspath(sys.argv[0])
ABSPATH=os.path.dirname(ABSPATH)+"/" cf.read(ABSPATH +'digest.conf')
利用PYTHON3.5构建WINDOWS服务
功能介绍:
利用PYTHON服务,向用户进行数据推送服务
实现的功能:
1、客户端验证
2、配置文件加解密
3、MSSQL数据库的读取
4、日志记录
服务端:
#!/usr/bin/env python
# -*- coding: UTF8 -*-
import win32serviceutil
import win32service
import win32event
import win32timezone
import sys
import servicemanager
import os,sys,socket
rootdir =os.path.abspath(sys.argv[0])
rootdir =os.path.dirname(rootdir) +"/"
import select,pymssql,logging,configparser
from logging.handlers import TimedRotatingFileHandler
# 以下_mssql decimal 模块用于打包PY文件时
import _mssql
import decimal
import time,json
import threading
import hashlib
cf =configparser.ConfigParser()
cf.read(rootdir +'socket_server.conf') formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y/%m/%d %H:%M:%S')
logger = logging.getLogger("log") # name
logger.setLevel(logging.DEBUG)
try:
# 按1天进行日志切割,同时保存20天的日志
fh =TimedRotatingFileHandler(rootdir +"log/"+ "sock_server.log","d",1,20)
except:
os.makedirs(rootdir +"log/")
fh =TimedRotatingFileHandler(rootdir +"log/"+ "sock_server.log","d",1,20)
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
# 给log 添加Handler
logger.addHandler(fh) # 加密函数
def encrypt(s,key=20):
"""
加密方法
:param key:
:param s:
:return:
"""
b = bytearray(str(s).encode("gbk"))
n = len(b) # 求出 b 的字节数
c = bytearray(n*2)
j = 0
for i in range(0, n):
b1 = b[i]
b2 = b1 ^ key # b1 = b2^ key
c1 = b2 % 16
c2 = b2 // 16 # b2 = c2*16 + c1
c1 = c1 + 65
c2 = c2 + 65 # c1,c2都是0~15之间的数,加上65就变成了A-P 的字符的编码
c[j] = c1
c[j+1] = c2
j = j+2
return c.decode("gbk")
# 解密函数
def decrypt(s,key=20):
"""
解密方法
:param key:
:param s:
:return:
"""
c = bytearray(str(s).encode("gbk"))
n = len(c) # 计算 b 的字节数
if n % 2 != 0 :
return ""
n = n // 2
b = bytearray(n)
j = 0
for i in range(0, n):
c1 = c[j]
c2 = c[j+1]
j = j+2
c1 = c1 - 65
c2 = c2 - 65
b2 = c2*16 + c1
b1 = b2^ key
b[i]= b1
try:
return b.decode("gbk")
except:
return "failed"
# 初始华MSSQL类方法
class MSSQL:
"""
对pymssql的简单封装
pymssql库,该库到这里下载:http://www.lfd.uci.edu/~gohlke/pythonlibs/#pymssql
使用该库时,需要在Sql Server Configuration Manager里面将TCP/IP协议开启
用法:
"""
def __init__(self,host,user,pwd,db,port =1433):
self.host = host
self.port = port
self.user = user
self.pwd = pwd
self.db = db
def __GetConnect(self):
"""
得到连接信息
返回: conn.cursor()
"""
try:
if not self.db:
logger.info("没有设置数据库信息")
self.conn = pymssql.connect(host=self.host,port=self.port,user=self.user,password=self.pwd,database=self.db,charset="utf8")
cur = self.conn.cursor()
if not cur:
logger.info("连接数据库失败!")
else:
return cur
except Exception as E:
logger.info("连接数据库异常,请检查配置!错误信息:%s"%E)
def ExecQuery(self,sql):
"""
执行查询语句
返回的是一个包含tuple的list,list的元素是记录行,tuple的元素是每行记录的字段
"""
cur = self.__GetConnect()
cur.execute(sql)
resList = cur.fetchall()
# 查询完毕后必须关闭连接
self.conn.close()
return resList def ExecNonQuery(self,sql):
"""
执行非查询语句 调用示例:
cur = self.__GetConnect()
cur.execute(sql)
self.conn.commit()
self.conn.close()
"""
cur = self.__GetConnect()
cur.execute(sql)
self.conn.commit()
self.conn.close()
# SQL语句执行模块
def mssql(conn):
""" 对指定数据进行查询,并返回结果!"""
ms = MSSQL(host=cf.get("DB","ip"),user=decrypt(cf.get("DB","username")),pwd=decrypt(cf.get("DB","password")),db=cf.get("DB","db"),port=int(cf.get("DB","port")))
x = 0
while True:
try:
sql ="select top 10 ChatContentID ,a.Siteid,ChatContent,ChatMemberName,ChatMemberLevelID,ChatMemberLevelTitle,AccMemberName,AccMemberLevelID,AccMemberLevelTitle,a.States,ChatType,IsPush,IsRobot,a.CreateDate,b.MemberID from dbo.ChatContent a left join Member b on a.ChatMemberPhone=b.Phone where ChatContentID !=0 and ChatType in (0,1,2,6) and ChatContentID>%s order by CreateDate desc"%x
res = ms.ExecQuery(sql)
if res != "":
x = res[0][0]
json_res = ""
result = {}
for i in res:
result["ChatContentID"]=i[0]
result["Siteid"] = i[1]
result["ChatContent"]=i[2]
result["ChatMemberName"]=i[3]
result["ChatMemberLevelID"] =i[4]
result["ChatMemberLevelTitle"] =i[5]
result["AccMemberName"] = i[6]
result["AccMemberLevelID"] =i[7]
result["AccMemberLevelTitle"] =i[8]
result["States"]=i[9]
result["ChatType"]=i[10]
result["IsPush"]=i[11]
result["IsRobot"] =i[12]
result["CreateDate"] =str(i[13])
result["MemberID"] = i[14]
json_res += json.dumps(result)+"\r\n"
conn.send(bytes(json_res,encoding="utf8"))
except Exception as e:
# 没有数据等待10秒
time.sleep(int(cf.get("TIME","conn_time")))
continue
# SOCKET主进程模块
def process(conn,addr): try:
i = 0
# 认证失败允许重试3次
while i < 3:
flage = False
# 接收客户端连接请求信息
info = conn.recv(1000)
# 实例化加密函数
hash = hashlib.sha512()
hash.update(bytes("",encoding="utf8")) # KEY=123
hash_pwd = hash.hexdigest()
if info.decode() == hash_pwd:
logger.info("客户端ip:[%s]认证成功!"%addr[0])
flage = True
# 接收用户及密码信息
while flage:
mssql(conn)
else:
# 登陆失败,发送给客户端重新验证
i += 1
logger.info("客户端ip:[%s]认证失败!"%addr[0])
conn.send(bytes("验证失败!","utf8"))
if i > 2:
# 主动关闭连接
logger.warning("客户端ip:[%s]超过认证限制,服务端强制中断连接!"%addr[0])
conn.close()
except Exception as e:
logger.debug(e)
conn.close()
# SOCKET服务模块
def sock_server():
'''
启动服务器端,开启线程监听
:return:
''' server = socket.socket()
server_ip=cf.get("HOST","ip")
server_port = int(cf.get("HOST","port"))
# server_ip ="localhost"
# server_port = 4561
server.bind((server_ip,server_port))
server.listen(10)
while True:
r,w,e = select.select([server,], [], [], 1)
for i,server in enumerate(r):
conn,addr = server.accept()
# 创建线程
t = threading.Thread(target=process, args=(conn, addr))
# 启动线程
t.start()
# 建立WINDOWS服务框架
class win32test(win32serviceutil.ServiceFramework): _svc_name_ = "socketserver"
_svc_display_name_ = "socketserver_display"
_svc_description_ = "socketserver_disc"
def __init__(self, args):
self.run = True
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcDoRun(self):
while self.run:
# 调用用户程序
sock_server()
win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
self.run =False
if __name__=='__main__':
if len(sys.argv) == 1:
try:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(win32test)
servicemanager.StartServiceCtrlDispatcher()
except:
win32serviceutil.usage() else:
win32serviceutil.HandleCommandLine(win32test)
客户端:
#!/usr/bin/env python3.5
# -*-coding:utf8-*-
"""
本实例客户端用于不断接收不定长数据,存储到变量res
"""
import socket,time,hashlib,json
ip_port = ('192.168.1.189',1888)
sk = socket.socket()
sk.connect(ip_port)
sk.setblocking(0) # 非阻塞模式,当接收没有发现任何数据时出异常 while True:
user_input=input("cmd>>:").strip()
# 重新初始化加密函数
hash = hashlib.sha512()
if len(user_input) ==0:continue
if user_input =="q":break
hash.update(bytes(user_input,encoding="utf8"))
hash_pwd = hash.hexdigest()
# print(hash_pwd) # 打印生成的加密函数
sk.send(bytes(hash_pwd,'utf8'))
res = ""
while True:
try:
time.sleep(0.1)
time1 = time.time()
server_replay = sk.recv(8000).decode()
res += str(server_replay)
except BlockingIOError:
time2 = time.time()
print("接收数据完成,耗时:%s秒" %(time2-time1))
break
result = res.split("\r\n")
try :
for i in result:
xx = json.loads(i,"utf8")
print(xx)
except Exception:
pass
res = "" sk.close()
python 3.5构建WINDOWS推送服务的更多相关文章
- [Win10应用开发] 使用 Windows 推送服务
前言 Windows 推送服务(WNS)也是 Win10 通知机制中的一种,今天与大家一起学习一下有关WNS的相关知识.使用 Windows 推送服务的前提是你需要有一个微软开发者账号,这样才能得到一 ...
- Windows 8.1——将网站固定到开始菜单,自定义图标、颜色和Windows推送通知
记得在IE 9和Windows 7刚出来那会儿我写过一篇文章来介绍如何自定义网站将其固定到Windows的任务栏上,同时自定义图标及任务内容.那个功能在IE 9中被称之为JumpList.http:/ ...
- 将网站固定到开始菜单,自定义图标、颜色和Windows推送通知
Windows 8.1——将网站固定到开始菜单,自定义图标.颜色和Windows推送通知 记得在IE 9和Windows 7刚出来那会儿我写过一篇文章来介绍如何自定义网站将其固定到Windows的任务 ...
- Erlang C1500K长连接推送服务-内存
上篇 Erlang C1500K长连接推送服务-性能 提到:150w连接,使用了23GB内存,每个连接占用15KB,约一半是内核使用. 大概分析一下: 1. Erlang 节点 12GB,内部因为有内 ...
- Mosquitto搭建Android推送服务(一)MQTT简介
总体概要: MQTT系列文章分为4部分 1.MQTT简介 2.mosquitto服务器搭建 3.编写Mosquitto的可视化工具 4.使用Mosquitto完成Android推送服务 文章钢要: 对 ...
- 移动互联网实战--Apple的APNS桩推送服务的实现(2)
前记: 相信大家在搞IOS推送服务的开发时, 会直接使用javapns api来简单实现, 调试也直连Apple的APNS服务(产品/测试版)来实现. 很少有人会写个APNS的桩服务, 事实也是如此. ...
- 移动互联网实战--Apple的APNS桩推送服务的实现(1)
前记: 相信大家在搞IOS推送服务的开发时, 会直接使用javapns api来简单实现, 调试也直连Apple的APNS服务(产品/测试版)来实现. 很少有人会写个APNS的桩服务, 事实也是如此. ...
- 2014年国内经常使用移动client推送服务介绍和比較
经过5年移动互联网的迅速发展,如今推送服务方面国内已经出现了非常多产品,比如极光推送,个推,一推,百度推送,友盟推送等,我们在选择推送服务时,首先排除了付费的推送服务,重点调查了免费的推送服务. ...
- 26.app后端怎么架设推送服务
推送服务已经是app的标配了.架设推送服务,除了可以使用第三方服务商外,也有大量的开源技术可以选择. 现在推送主要分两块,android推送和ios推送,在下面分别论述: 1. Android推 ...
随机推荐
- bootstrap插件学习-bootstrap.modal.js
bootstrap插件学习-bootstrap.modal.js 先从bootstrap.modal.js的结构看起. function($){ var Modal = function(){} // ...
- SystemTray文字颜色问题
今天想给SystemTray的ForegroundColor设置为白色,但是模拟器正确,真机仍为黑色.经过一番折腾,发现是微软做了限制,背景是什么颜色,ForegroundColor就不能为什么颜色. ...
- Linux CPU监控指标
Linux CPU监控指标 Linux提供了非常丰富的命令可以进行CPU相关数据进行监控,例如:top.vmstat等命令.top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执 ...
- 统计知识选讲(一)——主成分分析(PCA)的思想
主成分分析的主要目的是希望用较少的变量去解释原来资料中的大部分变异,将我们手中许多相关性很高的变量转化成彼此相互独立或不相关的变量,从而达到降维的目的.在原始数据“预处理”阶段通常要先对它们采用PCA ...
- FileTable初体验
FileTable初体验 阅读导航 启用FILESTREAM设置 更改FILESTRAM设置 启用数据库非事务性访问级别 FileTable 在我接触FileTable之前,存储文件都是存储文件的链接 ...
- Unable to start T-SQL Debugging. Could not connect to the computer ‘.’
Unable to start T-SQL Debugging. Could not connect to the computer ‘.’ 在Win7上面使用SSMS连接到SQL Server使用D ...
- 从零开始学C++之运算符重载(三):完善String类([]、 +、 += 运算符重载)、>>和<<运算符重载
在前面文章中使用过几次String类的例子,现在多重载几个运算符,更加完善一下,并且重载流类运算符. []运算符重载 +运算符重载 +=运算符重载 <<运算符重载 >>运算符重 ...
- 通过Jasmine和Guard自动测试JavaScript
原文标题:Autotesting JavaScript with Jasmine and Guard 原文地址:http://edspencer.net/2013/06/15/autotesting- ...
- ios-制作静态.a文件
一.制作静态库文件 /*静态库制作*/ // MakeA.h -(NSString*)testA; // MakeA.m -(NSString*)testA{ return @"静态库测试成 ...
- JAVA线程间的状态转换
线程间的状态转换: 1. 新建(new):新创建了一个线程对象. 2. 可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法.该状态的线程位于可运 ...