我们想获取数据我们就是客户端,能发送我们想要的数据的一方是服务端,我们相对获取的数据以话题的方式发布的代码如下
// 包含必要的ROS和标准头文件
#include <ros/ros.h>
#include <std_msgs/String.h>
#include "std_msgs/Int32.h"
// 包含套接字和网络库
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 10135 // 定义服务器端口号
int main(int argc, char **argv)
{
// 初始化ROS节点
ros::init(argc, argv, "laser_ranging_2");
ros::NodeHandle nh;
// 创建ROS发布者,发布std_msgs::String类型的消息
ros::Publisher pub = nh.advertise<std_msgs::String>("laser_ranging_2", 10);
// 创建TCP套接字
int sock = 0, valread;
struct sockaddr_in serv_addr;
char buffer[1024] = {0};
// 创建套接字文件描述符
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
ROS_ERROR("Socket creation error");
return -1;
}
// 指定服务器地址和端口
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// 将IPv4和IPv6地址从文本转换为二进制形式
if (inet_pton(AF_INET, "192.168.2.80", &serv_addr.sin_addr) <= 0)
{
ROS_ERROR("Invalid address/ Address not supported");
return -1;
}
// 连接到服务器
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
ROS_ERROR("Connection Failed");
return -1;
}
// 主循环接收数据
while (ros::ok())
{
// 从服务器读取数据
valread = read(sock, buffer, 1024);
if (valread > 0)
{
// 打印接收到的消息
// ROS_INFO("Received message: %s", buffer);
// 发布消息到ROS话题
std_msgs::String msg;
msg.data = buffer;
pub.publish(msg);
}
}
return 0;
}
我们需要知道服务端的ip和端口。
还有一种情况是我们需要发送特定的数据给服务端,服务端才会给我们数据。这种情况我们需要先发送一遍特定的数据去唤醒服务端在发送一边数据给服务端,才能获取到一遍数据(想要一直有数据就要一直发送特定的数据给服务端)。
当我们获取到的数据是以字节的形式时我们需要解析报文来得到数据。