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推 ...
随机推荐
- DeviceIoControl方式 sys和exe通信
常识: IRP:I/O Request Package 即输入输出请求包 exe和sys通信时,exe会发出I/O请求.操作系统会将I/O请求转化为相应的IRP数据, 不同类型传递到不同的d ...
- MongoDB学习2
MongoDB学习(翻译2) C#驱动之LINQ教程 介绍 本教程涵盖了1.8发布版本对linq查询的支持. 开始本教程之前,你应该至少阅读下C#驱动教程关于C#驱动的介绍 快速开始 首先,添加下面命 ...
- SQLSERVER之高灵活的业务单据流水号生成
SQLSERVER之高灵活的业务单据流水号生成 最近的工作中要用到流水号,而且业务单据流水号生成的规则分好几种,并非以前那种千篇一律的前缀+日期+流水号的简单形式,经过对业务的分析,以及参考网上程序员 ...
- linux下安装java
搞了一年IT了,作为IT人没怎么玩过linux挺丢脸的,要好好整整. 先从熟悉的来,在linux下开发java,首先要搭建环境. linux有一个工具yum,非常好用. 1.yum install j ...
- .NET开发规范教程
.NET开发规范教程 这是1年多以前我在公司所做讲座的讲义,现在与园友们分享,欢迎拿去使用.一起讨论.文中有若干思考题,对园友们是小菜一碟.另有设计模式讲义一篇,随后发布. 1 概述 1.1 意义 “ ...
- hdu4474 Yet Another Multiple Problem
Yet Another Multiple Problem Description There are tons of problems about integer multiples. Despite ...
- kubernetes源码阅读及编译
kubernetes源码阅读 工欲善其事,必先利其器.在阅读kubernetes源码时,我也先后使用过多个IDE,最终还是停留在IDEA上. 我惯用的是pycharm(IDEA的python IDE版 ...
- js动画(一)
终于放寒假了,哈哈哈,然后,也不准备闲着吧,就是再熟悉一下旧的东西,然后把新的东西也拿来分享一下,自己也准备好了再这个寒假 好好的提高一下自己,哎,菜鸟一枚,真正去实战了,发现自己手上的武器太少了,所 ...
- Java入门第二季第一章类和对象知识点
Java 中的 static 使用之静态方法 1. 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员.如: 如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问 ...
- iOS开发-OC语言 (一)oc数据类型
分享一套以前学习iOS开发时学习整理的资料,后面整套持续更新: oc数据类型 数据类型:基本数据类型.指针数据类型 基本数据类型:数值型.字符型(char).布尔型.空类型(void) 指针数据类型: ...