当前自己做的一个东西是有关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=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()
客户端
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;
class __CHJ_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;
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);
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);
}
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;
}
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);
}
}