win下python3与C++进行socket通信

来源:互联网 发布:淘宝网天猫食品 编辑:程序博客网 时间:2024/06/08 15:59

当前自己做的一个东西是有关3D显示和算法控制的。
写算法的时候希望用python,而显示3D网格这些希望用opengl。一开始打算都用python,可是python的那些vtk,pyqt4似乎在python3上不好配置,总之自己弄了很长时间最后放弃了,就打算采用标题的这种方法,本以为这个在网上能够方便地搜到,没想到找了半天找不到合适的,于是简单拼凑出一个示例,记录一下。

不知道要实现数据传输有没有更好的方式,目前自己打算先采用这种。

思路:
python作为服务端,c++作为客户端,二者互传数据。
注意点:
1. python中最好用ascii编码和解码
2. 这里使用的是TCP
3. 中文的传递也弄出来了,原来c++那个传过来的中文是GBK格式的,因此python的decode要改成recv_str.decode('gbk'),之前用utf-8一直有问题,python中直接输出来是b'\x0c...'这种

服务器端(先运行)

import socketimport osimport timeif __name__ == '__main__':    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    server.bind(("localhost", 8888))    server.listen(0)    while True:        connection, address = server.accept()        print(connection, address)        recv_str=connection.recv(1024)[0:5]        #recv_str=str(recv_str)  这样不行带有了b''        recv_str=recv_str.decode("ascii")        print( recv_str,len(recv_str) )        connection.send( bytes("test: %s" % recv_str,encoding="ascii") )        time.sleep( 0.5 )    connection.close()    input()

客户端

#include <stdio.h>  #include <Winsock2.h>  #pragma comment(lib,"ws2_32.lib")int main(){    WORD wVersionRequested;    WSADATA wsaData;    int err;    wVersionRequested = MAKEWORD(1, 1);    err = WSAStartup(wVersionRequested, &wsaData);    if (err != 0) {        return -1;    }    if (LOBYTE(wsaData.wVersion) != 1 ||        HIBYTE(wsaData.wVersion) != 1) {        WSACleanup();        return -1;    }    SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);    SOCKADDR_IN addrSrv;    addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");    addrSrv.sin_family = AF_INET;    addrSrv.sin_port = htons(8888);    connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));    send(sockClient, "hello", strlen("hello") + 1, 0);    char recvBuf[50];    recv(sockClient, recvBuf, 50, 0);    printf("%s\n", recvBuf);    closesocket(sockClient);    WSACleanup();    getchar();    return 0;}

自己关于C++socket的整理

#pragma once#include <winsock2.h>#include <windows.h>#pragma comment(lib,"ws2_32.lib")#include <stdio.h> #include <iostream>#include <string>using namespace std;// WSA 的部分class __CHJ_WSA {//public:    //const static __CHJ_WSA wsa;private:    const static __CHJ_WSA wsa;    bool isOk;    __CHJ_WSA() {        isOk = false;        WORD wVersionRequested;        WSADATA wsaData;        int err;        wVersionRequested = MAKEWORD(1, 1);        err = WSAStartup(wVersionRequested, &wsaData);        if (err != 0) {            exit(-100);        }        if (LOBYTE(wsaData.wVersion) != 1 ||            HIBYTE(wsaData.wVersion) != 1) {            WSACleanup();            exit(-101);        }        isOk = true;        cout << "CHJ_WSA OK~~" << endl;    }    ~__CHJ_WSA() {        if(isOk) WSACleanup();    }};const __CHJ_WSA __CHJ_WSA::wsa;// SOCKET 定义部分// class __CHJ_SOCKET {    bool isciose;public:    SOCKET skt;    SOCKADDR_IN addrSrv;    __CHJ_SOCKET(string ip,int port,string type,int timeout=-1){        if (type == "tcp") {            skt = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);        }else if (type == "udp") {            skt = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);        }else {            printf("tcp or udp");            exit(-102);        }        if (timeout > 0) {            // 设置发送和接受的时间            if (::setsockopt(skt, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) == SOCKET_ERROR)  {                exit(-103);            }            if (::setsockopt(skt, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) == SOCKET_ERROR)  {                exit(-104);            }        }        addrSrv.sin_addr.S_un.S_addr = inet_addr(ip.c_str());        addrSrv.sin_family = AF_INET;        addrSrv.sin_port = htons(port);        //addrSrv.sin_addr.S_un.S_addr = INADDR_ANY;        isciose = false;    }    void close() {        if (isciose) {            closesocket(skt);            isciose = true;        }    }    ~__CHJ_SOCKET() {        if(isciose)closesocket(skt);    }};/////////////////////void tcp_server() {    __CHJ_SOCKET chj_socketcls("127.0.0.1",8888,"tcp");    SOCKET& skt = chj_socketcls.skt;    SOCKADDR_IN& addrSrv = chj_socketcls.addrSrv;    if (bind(skt, (LPSOCKADDR)&addrSrv, sizeof(addrSrv)) == SOCKET_ERROR) {        printf("bind error !");        return;    }    if (listen(skt, 5) == INVALID_SOCKET) {        printf("socket error !");        return;    }    SOCKET sClient;    sockaddr_in remoteAddr;    int nAddrlen = sizeof(remoteAddr);    char revData[255];    while (true)    {        printf("等待连接...\n");        sClient = accept(skt, (SOCKADDR *)&remoteAddr, &nAddrlen);        if (sClient == INVALID_SOCKET)        {            printf("accept error !");            continue;        }        printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));        //接收数据        int ret = recv(sClient, revData, 255, 0);        if (ret > 0)        {            revData[ret] = 0x00;            printf(revData);        }        //发送数据        char * sendData = " hello client \n";        send(sClient, sendData, strlen(sendData), 0);        closesocket(sClient);    }}void tcp_client() {    __CHJ_SOCKET chj_socketcls("127.0.0.1", 8888, "tcp");    SOCKET& sockClient = chj_socketcls.skt;    SOCKADDR_IN& addrSrv = chj_socketcls.addrSrv;    connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));    send(sockClient, "hello", strlen("hello") + 1, 0);    char recvBuf[50];    recv(sockClient, recvBuf, 50, 0);    printf("%s\n", recvBuf);}//// UDPvoid udp_server() {    __CHJ_SOCKET chj_socketcls("127.0.0.1", 8888, "udp");    SOCKET& skt = chj_socketcls.skt;    SOCKADDR_IN& addrSrv = chj_socketcls.addrSrv;    if (bind(skt, (LPSOCKADDR)&addrSrv, sizeof(addrSrv)) == SOCKET_ERROR) {        printf("bind error !");        return;    }    // 不需要listen    sockaddr_in remoteAddr;    int nAddrlen = sizeof(remoteAddr);    char revData[255];    while (true)    {        char recvData[255];        int ret = recvfrom(skt, recvData, 255, 0, (sockaddr *)&remoteAddr, &nAddrlen);        if (ret > 0)        {            recvData[ret] = 0x00;            printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));            printf(recvData);        }        char * sendData = "一个来自服务端的UDP数据包\n";        sendto(skt, sendData, strlen(sendData), 0, (sockaddr *)&remoteAddr, nAddrlen);    }}void udp_client() {    __CHJ_SOCKET chj_socketcls("127.0.0.1", 8888, "udp");    SOCKET& sockClient = chj_socketcls.skt;    SOCKADDR_IN& addrSrv = chj_socketcls.addrSrv;    int len = sizeof(addrSrv);    char * sendData = "来自客户端的数据包\n";    sendto(sockClient, sendData, strlen(sendData), 0, (sockaddr *)&addrSrv, len);    char recvData[255];    int ret = recvfrom(sockClient, recvData, 255, 0, (sockaddr *)&addrSrv, &len);    if (ret > 0)    {        recvData[ret] = 0x00;        printf(recvData);    }}