首页
社区
课程
招聘
[原创]python socket 服务端 与 c++客户端通讯,发包内容加密,支持大文件,并发
发表于: 2018-5-5 12:05 3875

[原创]python socket 服务端 与 c++客户端通讯,发包内容加密,支持大文件,并发

2018-5-5 12:05
3875

代码经过网络搜索,综合算是原创吧.py脚本为服务端
项目文件在
https://github.com/jinjie412/service_client_socket

import socketserver
import json
import base64
import os
from te import OPMysql,Caltime
import time

#数据库操作
opm = OPMysql()

#加密发包内容
def crypt(source,key):
    from itertools import cycle
    result=''
    temp=cycle(key)
    for ch in source:                        
      result=result+chr(ord(ch)^ord(next(temp))^ord('1'))
    return result
def jiami(f,key):
    if os.path.isfile(f):
        f=open(f,encoding='gbk')
        content=f.read()
        # print(content)
        f.close()

        print(content)
        # content=content.encode(encoding='gbk')
        content=crypt(content,key)
        print(content)
        content=crypt(content,key)
        print(content)
        content=content.encode(encoding='gbk')
        print(content)
        file_size = len(content)
        return file_size,content
    else:
        return None,False

#数据库搜索客户端发送来的信息有效性
def yz(datajs):
    sql = "select id,user,dqsj,rjbh from kh where user='%s' and rjbh='%s'" %(datajs['user'],datajs['rjbh'])
    res = opm.op_select(sql)
    #验证用户有效性
    if res:
        # print(res)
        timeArray = time.strptime(res[2], "%Y-%m-%d %H:%M:%S")
        # print(timeArray)
        #验证用户卡是否到期
        dt=Caltime(time.localtime(),timeArray)
        return dt
    else:
        return False


class myTCPhandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            self.data = self.request.recv(1024).decode('gbk', 'ignore').strip()
            if not self.data : break
            self.data=base64.b64decode(self.data)
            print(self.data)
            datajs = json.loads(self.data)
            print(datajs)
            if yz(datajs):
                #发送数据长度,发送数据内容
                dsize,data = jiami('./js/'+datajs["jb"],datajs['key'])  
                if dsize:
                    #向客户端发送数据长度
                    self.feedback_data =  ('%d' % (dsize,)).encode('gbk')
                    self.request.sendall(self.feedback_data)
                    #等待客户端返回
                    feedback = self.request.recv(100).decode('gbk', 'ignore').strip() #等待客户端确认
                    print(feedback)
                    if int(feedback) == dsize:
                        #发送所有数据
                        self.request.sendall(data)
                else:
                    print('open file error')
            else:
                print('erro')
                self.feedback_data = 'erro'.encode('gbk')
                self.request.sendall(base64.b64encode(self.feedback_data))

    def finish(self):  
        print("client is disconnect!")  

host = '127.0.0.1'
port = 9090
server = socketserver.ThreadingTCPServer((host,port),myTCPhandler)
server.serve_forever()

te.py 文件
使用了数据库连接池,网络搜索

import MySQLdb
from DBUtils.PooledDB import PooledDB
import time
import datetime

mysqlInfo = {
    "host": 'localhost',
    "user": 'root',
    "passwd": '000000',
    "db": 'w',
    "port": 3306,
    "charset": 'utf8'
}
class OPMysql(object):

    __pool = None

    def __init__(self):
        # 构造函数,创建数据库连接、游标
        self.coon = OPMysql.getmysqlconn()
        self.cur = self.coon.cursor()


    # 数据库连接池连接
    @staticmethod
    def getmysqlconn():
        if OPMysql.__pool is None:
            __pool = PooledDB(creator=MySQLdb, mincached=5, maxcached=20, host=mysqlInfo['host'], user=mysqlInfo['user'], passwd=mysqlInfo['passwd'], db=mysqlInfo['db'], port=mysqlInfo['port'], charset=mysqlInfo['charset'])
            print(__pool)
        return __pool.connection()

    # 插入\更新\删除sql
    def op_insert(self, sql):
        pass

    # 查询
    def op_select(self, sql):
        try:
            # print('op_select', sql)
            self.cur.execute(sql)  # 执行sql
            select_res = self.cur.fetchone()  # 返回结果为字典
            # select_res =self.cur.fetchall()
            return select_res
        except Exception as e:
            print(str(e))
            return False


    #释放资源
    def dispose(self):
        self.coon.close()
        self.cur.close()
#计算到期时间
def Caltime(date1,date2):  
  date1=datetime.datetime(date1[0],date1[1],date1[2],date1[3],date1[4],date1[5])
    date2=datetime.datetime(date2[0],date2[1],date2[2],date2[3],date2[4],date2[5])
    return date2>date1

if __name__ == '__main__':
    #申请资源
    opm = OPMysql()

    sql = "select id,user,dqsj,rjbh from w_kh where user='000' and rjbh='000'"
    res = opm.op_select(sql)
    print(res)
    timeArray = time.strptime(res[2], "%Y-%m-%d %H:%M:%S")
    print(timeArray)
    dt=Caltime(time.localtime(),timeArray)
    print(dt)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2018-5-5 12:27 被进口坚果编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 227
活跃值: (30)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2

c++ 客户端

//根据DataLen接收指定长度在返回
BOOL mRecv(SOCKET Socket, BYTE *RecvBuf, int DataLen)
{
    int nRetVal = 0, TotalBytesRecv = 0;
    while (TotalBytesRecv < DataLen)
    {
        nRetVal = recv(Socket, (char*)(RecvBuf + TotalBytesRecv), DataLen - TotalBytesRecv, 0);
        if (nRetVal <= 0)
            return TRUE;
        else
            TotalBytesRecv += nRetVal;
    }
    return FALSE;
}
//解密服务端发送的内容
VOID jiemi(PBYTE p, int len, string key)
{

    for (int i = 0; i < len; i++)
    {

        for (string::iterator ite = key.begin(); ite != key.end(); ite++) 
        {
            p[i]=p[i]^(*ite)^'1';
        }
    }

}
参数 sret:返回服务端发送的解密完成的数据
     user:用户
     rjbh:验证
     jb:向服务器请求的文本
     key:秘钥,发送到服务器,服务器根据秘钥加密数据
int get_js(string &sret, string user="000", string rjbh="000", string jb = "1.txt",string key="555")
{
    const int BUF_SIZE = 1024;

    WSADATA wsd; //WSADATA变量  
    SOCKET sHost; //服务器套接字  
    SOCKADDR_IN servAddr; //服务器地址  
    char buf[BUF_SIZE]; //接收数据缓冲区  
    char bufRecv[BUF_SIZE];
    int retVal; //返回值  
                //初始化套结字动态库  
    if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
    {
        cout << "WSAStartup failed!" << endl;
        return -1;
    }
    //创建套接字  
    sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == sHost)
    {
        cout << "socket failed!" << endl;
        WSACleanup();//释放套接字资源  
        return  -1;
    }

    //设置服务器地址  
    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    servAddr.sin_port = htons((short)9090);
    int nServAddlen = sizeof(servAddr);

    //连接服务器  
    retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
    if (SOCKET_ERROR == retVal)
    {
        cout << "connect failed!" << endl;
        closesocket(sHost); //关闭套接字  
        WSACleanup(); //释放套接字资源  
        return -1;
    }

    //向服务器发送数据  
    ZeroMemory(buf, BUF_SIZE);
    ZeroMemory(bufRecv, BUF_SIZE);
    sprintf(buf, "{\"user\":\"%s\",\"rjbh\":\"%s\",\"jb\":\"%s\",\"key\":\"%s\"}", user.c_str(), rjbh.c_str(), jb.c_str(),key.c_str());
    BASE64_Encode((PBYTE)buf, strlen(buf), bufRecv);
    retVal = send(sHost, bufRecv, strlen(bufRecv), 0);
    if (SOCKET_ERROR == retVal)
    {
        cout << "send failed!" << endl;
        closesocket(sHost); //关闭套接字  
        WSACleanup(); //释放套接字资源  
        return -1;
    }

    ZeroMemory(bufRecv, BUF_SIZE);
    recv(sHost, bufRecv, BUF_SIZE, 0); // 接收服务器端的数据
    int str_size = atoi(bufRecv);
    retVal = send(sHost, bufRecv, strlen(bufRecv), 0);//发送文件长度
    if (SOCKET_ERROR == retVal)
    {
        cout << "send failed!" << endl;
        closesocket(sHost); //关闭套接字  
        WSACleanup(); //释放套接字资源  
        return -1;
    }


    PBYTE data_buf_base64 = new BYTE[str_size + 1];
    RtlZeroMemory(data_buf_base64, str_size + 1);
    mRecv(sHost, data_buf_base64, str_size);
    int ilen = strlen((char*)data_buf_base64);
    if (ilen == str_size)
    {
        jiemi(data_buf_base64, ilen, key);
    }

    sret =(char*)data_buf_base64;
    delete[]data_buf_base64;


//退出  
    closesocket(sHost); //关闭套接字  
    WSACleanup(); //释放套接字资源  
    return 1;
}
最后于 2018-5-5 12:10 被进口坚果编辑 ,原因:
2018-5-5 12:06
0
游客
登录 | 注册 方可回帖
返回
//