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

当前自己做的一个东西是有关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 socket
import os
import time

if __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);

}

 UDP

void 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);
    }

}
  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值