问题:
C++项目调用python做的模型, 最开始的想法是system调用命令行bash进行python的调用,但是
C++是一个循环, 每次调用python都会重新load一遍python模型, 这样会浪费很多时间

we are using a variety of methods and approaches to settle the qustion.

  • 通过C++调用python的API接口, 在程序启动时一次load python模型,后面直接调用模型得到相关输出即可
  • 通过将python模型转化为C++的格式, 这里应该有相应的工具来转换, 比如python模型的tf2转化为c的tf2模型
  • 通过开辟共享内存, 共享文件, 从而将python的输出共享给C++ , 从而实现双方的通信

继上一篇c/c++调用python
本文主要介绍使用网络通信, 本地C

一. python与python交互

1.1 python TCP socket服务器

# python socket_server.py
# 这里python作为服务器, 等待stoke每次的访问
import socket
def tcpServer():
    host = "127.0.0.1"
    port = 5000
    s = socket.socket()
    s.bind((host, port))
    s.listen(1)  # 只能同时连接一个
    my_server, address = s.accept()
    print("connection from ", str(address))
    while True:
        data = my_server.recv(1024)  # 接收buffer的大小
        if not data:
            break
        print("from connected user ", str(data))
        data = str(data).upper()
        print("sending data ", data)
        my_server.send(data.encode())
    my_server.close()
if __name__ == '__main__':
    tcpServer()

1.2 python TCP socket客户端

python socket_client.py
# 这里python作为服务器, 等待stoke每次的访问
import socket
def tcpClient():
    host = "127.0.0.1"
    port = 5000

    s = socket.socket()
    s.connect((host, port))

    message = input("->")
    while message != 'q':
        s.send(message.encode())
        data = s.recv(1024)
        print("Received from server "+ str(data))
        message = input("->")
    s.close()
if __name__ == '__main__':
    tcpClient()

首先启动服务器,然后通过客户端连接到服务器
在这里插入图片描述

二. C++

2.1 服务器

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>

#define MAXLINE 4096
int main(int argc, char** argv){
    int  listenfd, connfd;
    struct sockaddr_in  servaddr;
    char  buff[4096];
    int  n;

    if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
        printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
        return 0;
    }

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(6666);

    if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
        printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
        return 0;
    }

    if( listen(listenfd, 10) == -1){
        printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
        return 0;
    }

    printf("======waiting for client's request======\n");
    while(1){
        if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){
            printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
            continue;
        }
        n = recv(connfd, buff, MAXLINE, 0);
        buff[n] = '\0';
        printf("recv msg from client: %s\n", buff);
        close(connfd);
    }
    close(listenfd);
    return 0;
}

2.2 客户端

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>

#define MAXLINE 4096

int main(int argc, char** argv){

    int   sockfd, n;
    char  buff_res[4096], sendline[4096];
    struct sockaddr_in  servaddr;

    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);
        return 0;
    }

    memset(&servaddr, 0, sizeof(servaddr)); //清空
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(5000);
    if( inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr) <= 0){
        printf("inet_pton error for %s\n",argv[1]);
        return 0;
    }

    if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
        printf("connect error: %s(errno: %d)\n",strerror(errno),errno);
        return 0;
    }

    printf("send msg to server: \n");
    while(1){

        // 这里改成咱们的code给sendline
        fgets(sendline, 4096, stdin); 
        if( send(sockfd, sendline, strlen(sendline), 0) < 0){
            printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
            return 0;
        } // 发送信息

        n = recv(sockfd, buff_res, MAXLINE, 0); //接收信息
        buff_res[n] = '\0';
        printf("recv msg from client: %s\n", buff_res);
    }
    close(sockfd);
    return 0;
}

在这里插入图片描述

三. python服务器, C++客户端

# 这里python作为服务器, 等待stoke每次的访问
import socket
import time
def tcpServer():
    host = "127.0.0.1"
    port = 5000
    s = socket.socket()
    s.bind((host, port))
    s.listen(1)  # 只能同时连接一个
    my_server, address = s.accept()
    print("connection from ", str(address))
    while True:
        data = my_server.recv(1024)  # 接收buffer的大小
        if not data:
            break
        print("from connected user ", str(data))
        data = str(data).upper()
        print("sending data ", data)
        my_server.send(data.encode())
        time.sleep(2)
    my_server.close()
if __name__ == '__main__':
    tcpServer()
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>

#define MAXLINE 4096


char  buff_res[4096]; 
char * sendline;
int get_client_connnect(){
    int   my_server;
    struct sockaddr_in  servaddr;
    if( (my_server = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);
        return 0;
    }
    memset(&servaddr, 0, sizeof(servaddr)); //清空
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(5000);
    if( inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr) <= 0){
        printf("inet_pton error for 127.0.0.1:5000\n");
        return 0;
    }

    if( connect(my_server, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
        printf("connect error: %s(errno: %d)\n",strerror(errno),errno);
        return 0;
    }
    return my_server;
}

int get_action(char * code, int my_server){
        if( send(my_server, code, strlen(code), 0) < 0){
            printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
            return 0;
        } // 发送信息
        int n;
        n = recv(my_server, buff_res, MAXLINE, 0); //接收信息
        buff_res[n] = '\0';
        printf("recv msg from client: %s\n", buff_res);
        return 2;
}

int main(int argc, char** argv){
    int my_server = get_client_connnect();
    int action = -1;
    printf("send msg to server: \n");
    while(1){

        // 这里改成咱们的code给sendline, 需要先将code转化为一行, 比如回车
        // fgets(sendline, 4096, stdin);
        sendline = "shgdsh\nsagahd\n"; 
        action = get_action(sendline,my_server); //向服务器my_server发送数据
    }
    close(my_server);
    return 0;
}

应用1. python socket 多客户端访问单服务器

# 服务器端
import socket  # 导入 socket 模块
from threading import Thread
 
ADDRESS = ('127.0.0.1', 5011)  # 绑定地址
 
g_socket_server = None  # 负责监听的socket
 
g_conn_pool = []  # 连接池

def init():
    """
    初始化服务端
    """
    global g_socket_server
    g_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建 socket 对象
    g_socket_server.bind(ADDRESS)
    g_socket_server.listen(5)  # 最大等待数(有很多人理解为最大连接数,其实是错误的)
    print("服务端已启动,等待客户端连接...")

def accept_client():
    """
    接收新连接
    """
    while True:
        client, _ = g_socket_server.accept()  # 阻塞,等待客户端连接
        # 加入连接池
        g_conn_pool.append(client)
        # 给每个客户端创建一个独立的线程进行管理
        thread = Thread(target=message_handle, args=(client,))
        # 设置成守护线程
        thread.setDaemon(True)
        thread.start()

def message_handle(client):
    """
    消息处理
    """
    client.sendall("连接服务器成功!".encode(encoding='utf8'))
    while True:
        data = client.recv(1024)  # 接收buffer的大小
        if not data:
            break
        print("from connected user ", str(data))
        data = str(data).upper()
        print("sending data ", data)
        client.send(data.encode())

    client.close()# 删除连接
    g_conn_pool.remove(client)
    print("有一个客户端下线了。")

if __name__ == '__main__':
    init()
    # 新开一个线程,用于接收新连接
    thread = Thread(target=accept_client)
    thread.setDaemon(True)
    thread.start()
    # 主线程逻辑
    while True:
        cmd = input("""--------------------------
                    输入1:查看当前在线人数
                    输入2:给指定客户端发送消息
                    输入3:关闭服务端
                    """)
        if cmd == '1':
            print("--------------------------")
            print("当前在线人数:", len(g_conn_pool))
        elif cmd == '2':
            print("--------------------------")
            index, msg = input("请输入“索引,消息”的形式:").split(",")
            g_conn_pool[int(index)].sendall(msg.encode(encoding='utf8'))
        elif cmd == '3':
            exit()


# 客户端
# 这里python作为服务器, 等待stoke每次的访问
import socket
ip_port=("127.0.0.1",5011)

def tcpClient():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(ip_port)

    message = input("->")
    while "quit" not in message:
        s.send(message.encode())
        data = s.recv(1024)
        print("Received from server "+ str(data))
        message = input("->")
    s.close()



if __name__ == '__main__':
    tcpClient()
  • 结果
    在这里插入图片描述
    注意:该应用是借鉴博主的, 如有侵犯请私聊删除😄
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐