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推送服务的更多相关文章

  1. [Win10应用开发] 使用 Windows 推送服务

    前言 Windows 推送服务(WNS)也是 Win10 通知机制中的一种,今天与大家一起学习一下有关WNS的相关知识.使用 Windows 推送服务的前提是你需要有一个微软开发者账号,这样才能得到一 ...

  2. Windows 8.1——将网站固定到开始菜单,自定义图标、颜色和Windows推送通知

    记得在IE 9和Windows 7刚出来那会儿我写过一篇文章来介绍如何自定义网站将其固定到Windows的任务栏上,同时自定义图标及任务内容.那个功能在IE 9中被称之为JumpList.http:/ ...

  3. 将网站固定到开始菜单,自定义图标、颜色和Windows推送通知

    Windows 8.1——将网站固定到开始菜单,自定义图标.颜色和Windows推送通知 记得在IE 9和Windows 7刚出来那会儿我写过一篇文章来介绍如何自定义网站将其固定到Windows的任务 ...

  4. Erlang C1500K长连接推送服务-内存

    上篇 Erlang C1500K长连接推送服务-性能 提到:150w连接,使用了23GB内存,每个连接占用15KB,约一半是内核使用. 大概分析一下: 1. Erlang 节点 12GB,内部因为有内 ...

  5. Mosquitto搭建Android推送服务(一)MQTT简介

    总体概要: MQTT系列文章分为4部分 1.MQTT简介 2.mosquitto服务器搭建 3.编写Mosquitto的可视化工具 4.使用Mosquitto完成Android推送服务 文章钢要: 对 ...

  6. 移动互联网实战--Apple的APNS桩推送服务的实现(2)

    前记: 相信大家在搞IOS推送服务的开发时, 会直接使用javapns api来简单实现, 调试也直连Apple的APNS服务(产品/测试版)来实现. 很少有人会写个APNS的桩服务, 事实也是如此. ...

  7. 移动互联网实战--Apple的APNS桩推送服务的实现(1)

    前记: 相信大家在搞IOS推送服务的开发时, 会直接使用javapns api来简单实现, 调试也直连Apple的APNS服务(产品/测试版)来实现. 很少有人会写个APNS的桩服务, 事实也是如此. ...

  8. 2014年国内经常使用移动client推送服务介绍和比較

    经过5年移动互联网的迅速发展,如今推送服务方面国内已经出现了非常多产品,比如极光推送,个推,一推,百度推送,友盟推送等,我们在选择推送服务时,首先排除了付费的推送服务,重点调查了免费的推送服务.   ...

  9. 26.app后端怎么架设推送服务

    推送服务已经是app的标配了.架设推送服务,除了可以使用第三方服务商外,也有大量的开源技术可以选择. 现在推送主要分两块,android推送和ios推送,在下面分别论述: 1.    Android推 ...

随机推荐

  1. .NET PageAdmin CMS

    .NET PageAdmin CMS 完全破解步骤(非简单去版权) 其实当初我的目的是很纯洁的,只是想找一个简单的网站生成模板,由于对.net更熟悉一点,就去搜索了.net框架的CMS,看它的介绍挺强 ...

  2. EntityFrame Work 5 性能注意事项(转自MSDN)

    1.简介 对象关系映射框架是一种在面向对象的应用程序中提供数据访问抽象的便捷方式.对于 .NET 应用程序,Microsoft 推荐的 O/RM 是实体框架.但任何抽象都要考虑性能. 本白皮书旨在介绍 ...

  3. 什么是Numpy的ndarray

    什么是Numpy的ndarray 首先,Numpy的核心是ndarray. 然后,ndarray本质是数组,其不同于一般的数组,或者Python 的list的地方在于它可以有N 维(dimention ...

  4. 我的Pandas应用场景(2)

    上文交代了一些啰嗦事,本文开始,就要来点实际的了. 先来一个比较简单的场景: Given:一个包括N(极其复杂,这里取3个)个列的DataFrame:df,df包括index: And:对df所有列元 ...

  5. SQL Server 如何读写数据

    01. SQL Server 如何读写数据   一. 数据读写流程简要SQL Server作为一个关系型数据库,自然也维持了事务的ACID特性,数据库的读写冲突由事务隔离级别控制.无论有没有显示开启事 ...

  6. 定时器Timer不定时

    订餐系统之定时器Timer不定时 经过几天漫长的问题分析.处理.测试.验证,定时器Timer终于定时了,于是开始了这篇文章,希望对还在纠结于“定时器Timer不定时”的同学有所帮助,现在的方案,在系统 ...

  7. hadoop集群环境的搭建

    hadoop集群环境的搭建 今天终于把hadoop集群环境给搭建起来了,能够运行单词统计的示例程序了. 集群信息如下: 主机名 Hadoop角色 Hadoop jps命令结果 Hadoop用户 Had ...

  8. DDNS client on a Linux machine

    Using this tool -> inadyn apt-get install inadyn -y Usage: https://github.com/troglobit/inadyn#ex ...

  9. 【OpenMesh】创建一个正方体

    原文出处: http://openmesh.org/Documentation/OpenMesh-Doc-Latest/tutorial.html 这个例程演示了: 如何声明MyMesh 如何添加顶点 ...

  10. [置顶] Android图片异步加载之Android-Universal-Image-Loader

    将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...