之前连接的是雷达,发送的是string类型字符串,现在需要接收type16类型字符串
windows下的socket接收type16类型的字符串
这里我封装了两个函数,receiveFromServer用于通信,extractSubstring用于截取通信字段(截取02开头到03中间的信号)
//调用socket连接 接收信号以2开头3结尾中间的type16进制数据
std::string extractSubstring(const std::string& input) {
std::string str_sub;
std::string str = input;
str.erase(std::remove(str.begin(), str.end(), ' '), str.end()); //删除字符串中的空格 02 46 03 > 024603
std::string fieldValue;
std::string result;
for (size_t i = 0; i < str.length(); i += 2) {
fieldValue = str.substr(i, 2);
str_sub = str_sub + fieldValue;
if (str_sub.substr(0, 2) != "02") {
str_sub = "";
}
if (str_sub.substr(0, 2) == "02" && str_sub.substr(str_sub.length() - 2) == "03") {
if (str_sub.substr(2, 2) == "4e" ||
str_sub.substr(2, 2) == "44" ||
str_sub.substr(2, 2) == "43" ||
str_sub.substr(2, 2) == "53" ||
str_sub.substr(2, 2) == "54")
{
result += str_sub + "\n";
}
str_sub = "";
}
}
return result;
}
std::mutex data_mutex; // 数据锁
std::deque<std::string> data_queue; // 数据队列
void str_socket_1(std::string ip, int ip_id) {
// 初始化Winsock库
WSADATA wsaData;
int err = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (err != 0)
{
std::cout << "WSAStartup failed with error: " << err << std::endl;
return;
}
// 创建套接字
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
std::cout << "socket failed with error: " << WSAGetLastError() << std::endl;
WSACleanup();
return;
}
// 设置服务器地址和端口
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(ip.c_str());
serverAddr.sin_port = htons(ip_id);
// 连接到服务器
int ret = connect(sock, (SOCKADDR*)&serverAddr, sizeof(serverAddr));
if (ret == SOCKET_ERROR)
{
std::cout << "connect failed with error: " << WSAGetLastError() << std::endl;
closesocket(sock);
WSACleanup();
return;
}
// 循环接收数据
while (true) {
// 从服务器接收数据
unsigned char recvData[32];
ret = recv(sock, (char*)recvData, 32, 0);
if (ret == SOCKET_ERROR)
{
std::cout << "recv failed with error: " << WSAGetLastError() << std::endl;
break;
}
else
{
std::stringstream ss;
for (int i = 0; i < ret; i += 2)
{
uint16_t value = (uint16_t)(recvData[i] << 8) | recvData[i + 1];
ss << std::hex << std::setfill('0') << std::setw(4) << value << " ";
}
// 处理接收到的数据
std::string str_sub_1 = extractSubstring(ss.str());
{
std::lock_guard<std::mutex> lock(data_mutex);
data_queue.push_front(str_sub_1);
if (data_queue.size() > 5) {
data_queue.pop_back(); // 删除队列末
}
}
}
}
// 关闭套接字和Winsock库
closesocket(sock);
WSACleanup();
}
这里在windows下测试完成后需要转linux
这里是linux版本的socket 可以看到变更了头文件以及细微参数的变更 整体与windows都差不多
#include <iostream>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sstream>
#include <iomanip>
std::deque<std::string> data_queue; // 数据队列
//创建一个端口反复接收字段
void str_socket_1(std::string ip, int ip_id) {
// 创建套接字
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
perror("socket");
return;
}
// 设置服务器地址
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(ip.c_str());
serverAddr.sin_port = htons(ip_id);
// 连接到服务器
int ret = connect(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if (ret == -1) {
perror("connect");
close(sock);
return;
}
// 循环接收数据
while (true) {
// 从服务器接收数据
unsigned char recvData[32];
ret = recv(sock, recvData, sizeof(recvData), 0);
if (ret == -1) {
perror("recv");
break;
}
else if (ret == 0) {
std::cout << "Connection closed by the server." << std::endl;
break;
}
else {
std::stringstream ss;
for (int i = 0; i < ret; i += 2) {
uint16_t value = (uint16_t)(recvData[i] << 8) | recvData[i + 1];
ss << std::hex << std::setfill('0') << std::setw(4) << value << " ";
}
// 处理接收到的数据
std::string str_sub_1 = extractSubstring(ss.str());
{
std::lock_guard<std::mutex> lock(data_mutex);
data_queue.push_front(str_sub_1);
if (data_queue.size() > 5) {
data_queue.pop_back(); // 删除队列末尾的数据
}
}
}
}
// 关闭套接字
close(sock);
}