描述
Ubuntu系统下的python进程,与windows系统下的C++进程,通过Socket通信。
代码
Ubuntu端的python进程(server)
代码特点:可适用多个Ubuntu系统的电脑
代码功能:
- 接受客户端(client)发送过来的字符串
- 通过我自定义的方式,从字符串中解析出来数据
- 再将原数据发送回client
使用说明:
- 拷贝到Ubuntu系统下,通过命令
ifconfig
命令查看当前网络ip - 将代码中的
HOST
改成当前电脑的ip PORT
号可以自行填写- 补充:多个Ubuntu系统电脑使用时,每个电脑上的程序只需要更改成当前电脑ip即可使用,每个电脑的PORT号可以相同
# coding=utf-8
import socket # socket模块
import commands # 执行系统命令模块
import time
# 下面的函数功能:解析我自定义的字符串(可以删去)
def translationString(s):
pose = [0.0] * 6
strlist = s.split(',') # 用逗号分割str字符串,并保存到列表
i = 0
for value in strlist: # 循环输出列表值
pose[i] = float(value)
i = i + 1
return pose
HOST = '192.168.2.114'
PORT = 2000
m_s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 定义socket类型,网络通信,TCP
m_s.bind((HOST, PORT)) # 套接字绑定的IP与端口
m_s.listen(1) # 开始TCP监听
conn, addr = m_s.accept() # 接受TCP连接,并返回新的套接字与IP地址
print('Connected by', addr) # 输出客户端的IP地址
while 1:
commandString = conn.recv(100) # 把接收的数据实例化
print("received command string is: "+commandString)
time.sleep(10)
pose = translationString(commandString)
print(pose[0])
print(pose[1])
print(pose[2])
print(pose[3])
print(pose[4])
print(pose[5])
conn.send(commandString)
conn.close() # 关闭连接
Windows端的C++进程(client)
代码功能:
- 将需要发送的数据,使用自定义的方式(数据之前添加一个逗号),转化成一个字符串
- 向server传送这个字符串
- 等待server端的回复(没收到回复就一直等待)
main.cpp
#include <string>
#include "socket.h"
int main(int argc, char* argv[]) // argc是命令行总的参数个数
{
std::vector<double> pose;
pose.push_back(-0.6856600698311117);
pose.push_back(0.05632624773119734);
pose.push_back(0.5632555325191156);
pose.push_back(1.8018419365295855);
pose.push_back(-0.9861161881778492);
pose.push_back(-1.9320369212412984);
std::string command_string;
SocketClient windows2Ubuntu_1;
windows2Ubuntu_1.init("192.168.2.114", 2000);
command_string = windows2Ubuntu_1.transPose_to_String(pose);
windows2Ubuntu_1.sendCommand(command_string);
windows2Ubuntu_1.sendCommand(command_string);
windows2Ubuntu_1.sendCommand(command_string);
windows2Ubuntu_1.cancel();
SocketClient windows2Ubuntu_2;
windows2Ubuntu_2.init("192.168.2.110", 2000);
windows2Ubuntu_2.sendCommand(command_string);
windows2Ubuntu_2.sendCommand(command_string);
windows2Ubuntu_2.sendCommand(command_string);
windows2Ubuntu_2.cancel();
return 0;
}
Socket.h
#ifndef __SOCKET_H__
#define __SOCKET_H__
#include <stdio.h>
#include <Windows.h>
#include <string>
#include <iostream>
#include <vector>
#pragma comment(lib, "ws2_32.lib")
class SocketClient
{
public:
SocketClient();
~SocketClient();
int init(std::string ip, int port_num);
std::string transPose_to_String(std::vector<double> pose);
int sendCommand(std::string commandString);
int cancel();
public:
WSADATA m_s; // 用来储存调用AfxSocketInit全局函数返回的Windows Sockets初始化信息
SOCKET m_ClientSocket;
struct sockaddr_in m_ClientAddr; // 一个sockaddr_in型的结构体对象
char m_SendBuffer[MAX_PATH]; // Windows的MAX_PATH默认是260
};
#endif // !_SOCKET_H__
Socket.cpp
#include "socket.h"
SocketClient::SocketClient()
{
}
SocketClient::~SocketClient()
{
}
int SocketClient::init(std::string ip, int port_num)
{
// 初始化Windows Socket
// WSAStartup函数对Winsock服务的初始化
if (WSAStartup(MAKEWORD(2, 2), &m_s) != 0) // 通过连接两个给定的无符号参数,首个参数为低字节
{
printf("Init Windows Socket Failed! Error: %d\n", GetLastError());
return -1;
}
m_ClientSocket = socket(AF_INET, // 只支持ARPA Internet地址格式
SOCK_STREAM, // 新套接口的类型描述
IPPROTO_TCP); // 套接口所用的协议
if (m_ClientSocket == INVALID_SOCKET)
{
printf("Create Socket Failed! Error: %d\n", GetLastError());
return -1;
}
m_ClientAddr.sin_family = AF_INET;
m_ClientAddr.sin_addr.s_addr = inet_addr(ip.c_str()); // 定义IP地址
m_ClientAddr.sin_port = htons(port_num); // 将主机的无符号短整形数转换成网络字节顺序
memset(m_ClientAddr.sin_zero, 0X00, 8); // 函数通常为新申请的内存做初始化工作
// 连接Socket
int ret = connect(m_ClientSocket,
(struct sockaddr*)&m_ClientAddr,
sizeof(m_ClientAddr));
if (ret == SOCKET_ERROR)
{
printf("Socket Connect Failed! Error:%d\n", GetLastError());
return -1;
}
else
{
printf("Socket Connect Succeed!");
}
return 1;
}
int SocketClient::cancel()
{
// 关闭socket
closesocket(m_ClientSocket);
WSACleanup();
return 1;
}
std::string SocketClient::transPose_to_String(std::vector<double> pose)
{
std::string command_string;
std::string s[6];
for (int i = 0; i < 6; i++)
{
s[i] = std::to_string(pose[i]);
}
command_string = s[0];
for (int i = 1; i < 6; i++)
{
command_string.append(",");
command_string.append(s[i]);
}
return command_string;
}
int SocketClient::sendCommand(std::string commandString)
{
printf("Input Data: ");
std::cout << commandString << std::endl;
// 发送数据至服务器
int ret = send(m_ClientSocket, commandString.c_str(), (int)strlen(commandString.c_str()), 0);// 返回发送缓冲区数据长度
if (ret == SOCKET_ERROR)
{
printf("Send Information Failed! Error:%d\n", GetLastError());
}
int retVal;
char bufRecv[200];
memset(bufRecv, 0, sizeof(bufRecv));
while (1)
{
retVal = recv(m_ClientSocket, bufRecv, 200, 0);
if (retVal == SOCKET_ERROR) {
printf("recive faild!\n");
break;
}
else {
printf("收到服务器消息:%s\n", bufRecv);
break;
}
}
return 1;
}