当前自己做的一个东西是有关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);
}
}