socket通信(二)单个或多个Ubuntu系统的python进程与Windows系统的C++进程

描述

Ubuntu系统下的python进程,与windows系统下的C++进程,通过Socket通信。

代码

Ubuntu端的python进程(server)

代码特点:可适用多个Ubuntu系统的电脑

代码功能:

  1. 接受客户端(client)发送过来的字符串
  2. 通过我自定义的方式,从字符串中解析出来数据
  3. 再将原数据发送回client

使用说明:

  1. 拷贝到Ubuntu系统下,通过命令ifconfig命令查看当前网络ip
  2. 将代码中的HOST改成当前电脑的ip
  3. PORT号可以自行填写
  4. 补充:多个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)

代码功能:

  1. 将需要发送的数据,使用自定义的方式(数据之前添加一个逗号),转化成一个字符串
  2. 向server传送这个字符串
  3. 等待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;
}
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值