一个简单的socket项目

本文介绍了一个项目需求,通过AES加密数据,使用C++的mongoose作为HTTP客户端,与Python实现的socket服务器进行通信。由于gRPC在Windows上的C++客户端开发复杂,选择了HTTP协议。服务器端用Python方便操作数据库,而C++用于调用DLL进行加解密。最初通过GET请求传输少量加密数据,随后改为POST请求以发送大量数据,最终确认socket是最合适的选择。分享了部分源码作为记录。
摘要由CSDN通过智能技术生成

    就是有这么一个需求,把程序生成的数据文件内容加密,并且有一个解密程序,解密程序要把加密的数据上传到服务器,并且保存在服务器数据库和服务器磁盘里,在得到服务器验证之后要把数据在本地解密。

    加解密用的是AES算法。之前用过gRPC实现客户端和服务器的通信,但是加密需要用C++,C++在Windows上写gRPC客户端不太好搞,于是就想到了HTTP协议,在网上找了个开源的http webserver叫mongoose,用它做客户端,服务器用的是python的socket,python比较好操作数据库,但是使用解密算法和计算参数需要使用C++的DLL的导出函数,这个用的是ctypes来实现的。实现了用C++客户端发送get请求,只发送很少的加密数据到服务器,服务器把数据存到数据库并且返回验证参数,客户端在本地解密的功能。后来需要发送很长的数据,但是get请求有长度限制,就要用post请求了,但是我又不会post,找了一下最终决定客户端也用C++的socket了,很方便想发什么发什么,其实感觉这个需求的话一开始就应该直接用socket。socket跑出效果还是非常快的,这里把部分源码贴出来,做个记录。

服务端:

#这是python调用C++DLL的函数的方法
pDll = ctypes.WinDLL("C:/Users/Administrator/aurora111.dll")
strSrc = bytes(IMEI, encoding='utf-8')
#如果是返回字符串指针,那么就必须像下面这样修改返回类型
pDll.DecryptionAES.restype = ctypes.c_uint64
pointer = pDll.DecryptionAES(strSrc)
need_str = str(ctypes.string_at(pointer), encoding='utf-8', errors='ignore')
#python创建socket,监听端口,有用户连上就调用处理的函数
if __name__ == "__main__":
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(("", 8888))
    server_socket.listen(128)

    while True:
        client_socket, client_address = server_socket.accept()
        print("[%s, %s]用户连接上了" % client_address)
        handle_client_process = Process(target=handle_socket, args=(client_socket,))
        handle_client_process.start()
        client_socket.close()
#接受数据,发送数据,关闭连接
request_data = client_socket.recv(20480)
request_data = str(request_data, encoding='utf-8')
outkey = pDll.LicenseCheckCal(int(need_key))
response_body = str(outkey)
client_socket.send(bytes(response_body, 'utf-8'))
client_socket.close()
#MySQL提交事务,也是很简单了
def lockedExecute(sql):
    mysql_conn = pymysql.connect(host='127.0.0.1', port=3306, user='xxx', password='xxx', db='xxx')
    try:
        with mysql_conn.cursor() as cursor:
            cursor.execute(sql)
        mysql_conn.commit()
    except Exception as e:
        print(e)
        mysql_conn.rollback()
    finally:
        mysql_conn.close()
//C++socket
#include <WinSock2.h>
//记得附加ws2_32.lib
//初始化
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
//创建套接字
SOCKET clntSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
//向服务器发送消息
sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));			//每个字节都用0填充
sockAddr.sin_family = PF_INET;
sockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
sockAddr.sin_port = htons(8888);
connect(clntSock, (SOCKADDR*)& sockAddr, sizeof(SOCKADDR));
//发送消息
string sendToServerBuffer = "";
send(clntSock, sendToServerBuffer.c_str(), sendToServerBuffer.size(), 0);
//接收服务器消息
char responseBuffer[64] = { 0 };
recv(clntSock, responseBuffer, 64, 0);
//关闭套接字
closesocket(clntSock);
//终止dll
WSACleanup();
//C++递归获取文件夹内所有带路径的文件名
void get_files(std::string fileFolderPath, std::string fileExtension, std::vector<std::string>&file)
{
    std::string fileName;
    struct _finddata_t fileInfo;
    long long findResult;

    if ((findResult = _findfirst((fileFolderPath + "\\*").c_str(), &fileInfo)) != -1) {
        do {
            if ((fileInfo.attrib&_A_SUBDIR))
            {  //如果是文件夹;
                if (strcmp(fileInfo.name, ".") != 0 && strcmp(fileInfo.name, "..") != 0)
                {  //如果文件名不是.或者,,,则递归获取子文件中的文件;
                    get_files(fileFolderPath + "\\" + fileInfo.name, fileExtension, file);  //递归子文件夹;
                }

            }
            else   //如果是文件;
            {
                int c;
                c = strlen(fileInfo.name);
                if (fileInfo.name[c - 3] == fileExtension[1] && fileInfo.name[c - 2] == fileExtension[2] && fileInfo.name[c - 1] == fileExtension[3])
                {
                    file.push_back(fileFolderPath + "\\" + fileInfo.name);
                }
            }
            memset(fileInfo.name, 0, sizeof(fileInfo.name));
        } while (_findnext(findResult, &fileInfo) == 0);
        _findclose(findResult);
    }
}

C++的HTTP客户端直接参考mongoose示例代码即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值